73a544e7d5e5a2765320c723a9e5396e5c4a63d8
[moodle.git] / lib / datalib.php
1 <?PHP // $Id$
3 /// FUNCTIONS FOR DATABASE HANDLING  ////////////////////////////////
5 function execute_sql($command, $feedback=true) {
6 /// Completely general function - it just runs some SQL and reports success.
8     global $db;
9     
10     $result = $db->Execute("$command");
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 }
25 function modify_database($sqlfile="", $sqlstring="") {
26 /// Assumes that the input text (file or string consists of 
27 /// a number of SQL statements ENDING WITH SEMICOLONS.  The 
28 /// semicolons 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)
32     global $CFG;
34     $success = true;  // Let's be optimistic :-)
36     if (!empty($sqlfile)) {
37         if (!is_readable($sqlfile)) {
38             $success = false;
39             echo "<P>Tried to modify database, but \"$sqlfile\" doesn't exist!</P>";
40             return $success;
41         } else {
42             $lines = file($sqlfile);
43         }
44     } else {
45         $lines[] = $sqlstring;
46     }
48     $command = "";
50     foreach ($lines as $line) {
51         $line = rtrim($line);
52         $length = strlen($line);
54         if ($length and $line[0] <> "#") { 
55             if (substr($line, $length-1, 1) == ";") {
56                 $line = substr($line, 0, $length-1);   // strip ;
57                 $command .= $line;
58                 $command = str_replace("prefix_", $CFG->prefix, $command); // Table prefixes
59                 if (! execute_sql($command)) {
60                     $success = false;
61                 }
62                 $command = "";
63             } else {
64                 $command .= $line;
65             }
66         }
67     }
69     return $success;
71 }
73 /// FUNCTIONS TO MODIFY TABLES ////////////////////////////////////////////
75 function table_column($table, $oldfield, $field, $type="integer", $size="10",
76                       $signed="unsigned", $default="0", $null="not null", $after="") {
77 /// Add a new field to a table, or modify an existing one (if oldfield is defined).
78     global $CFG;
80     switch (strtolower($CFG->dbtype)) {
82         case "mysql":
83         case "mysqlt":
85             switch (strtolower($type)) {
86                 case "integer":
87                     $type = "INTEGER($size)";
88                     break;
89                 case "varchar":
90                     $type = "VARCHAR($size)";
91                     break;
92             }
94             if (!empty($oldfield)) {
95                 $operation = "CHANGE $oldfield $field";
96             } else {
97                 $operation = "ADD $field";
98             }
100             $default = "DEFAULT '$default'";
102             if (!empty($after)) {
103                 $after = "AFTER `$after`";
104             }
106             execute_sql("ALTER TABLE {$CFG->prefix}$table $operation $type $signed $default $null $after");
107             break;
109         case "postgres7":        // From Petri Asikainen
111             //to prevent conflicts with reserved words
112             $field = "\"$field\"";
113             $oldfield = "\"$oldfield\"";
115             switch (strtolower($type)) {
116                 case "integer":
117                     if ($size <= 2) {
118                         $type = "INT2";
119                     } 
120                     if ($size <= 4) {
121                         $type = "INT";
122                     }
123                     if  ($size > 4) {
124                         $type = "INT8";
125                     }
126                     break;
127                 case "varchar":
128                     $type = "VARCHAR($size)";
129                     break;
130             }
132             $default = "DEFAULT '$default'";
134             //After is not implemented in postgesql
135             //if (!empty($after)) {
136             //    $after = "AFTER '$after'";
137             //}
139             if (!empty($oldfield)) {
140                 execute_sql("ALTER TABLE {$CFG->prefix}$table RENAME COLUMN $oldfield TO $field");
141             } else {
142                 execute_sql("ALTER TABLE {$CFG->prefix}$table ADD COLUMN $field $type");
143             }
145             /* SETTING OF COLUMN TO NULL/NOT NULL
146                IS NOT POSIBLE BEFORE POSTGRESQL 7.3
147                THIS COMMENTED OUT UNTIL  I FIGuRE OUT HOW GET POSTGESQL VERSION FROM ADODB
149             //update default values to table
150             if ($null == "NOT NULL") {
151               execute_sql("UPDATE {$CFG->prefix}$table SET $field=$default where $field=NULL");
152               execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $null");
153             } else {
154                execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field DROP NOT NULL"
155             }
156             */
157   
158             execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $default");
160             break;
162         default:
163             switch (strtolower($type)) {
164                 case "integer":
165                     $type = "INTEGER";
166                     break;
167                 case "varchar":
168                     $type = "VARCHAR";
169                     break;
170             }
172             $default = "DEFAULT '$default'";
174             if (!empty($after)) {
175                 $after = "AFTER $after";
176             }
178             if (!empty($oldfield)) {
179                 execute_sql("ALTER TABLE {$CFG->prefix}$table RENAME COLUMN $oldfield $field");
180             } else {
181                 execute_sql("ALTER TABLE {$CFG->prefix}$table ADD COLUMN $field $type");
182             }
184             execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $null");
185             execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $default");
186             break;
188     }
193 /// GENERIC FUNCTIONS TO CHECK AND COUNT RECORDS ////////////////////////////////////////
195 function record_exists($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") {
196 /// Returns true or false depending on whether the specified record exists
198     global $CFG;
200     if ($field1) {
201         $select = "WHERE $field1 = '$value1'";
202         if ($field2) {
203             $select .= " AND $field2 = '$value2'";
204             if ($field3) {
205                 $select .= " AND $field3 = '$value3'";
206             }
207         }
208     } else {
209         $select = "";
210     }
212     return record_exists_sql("SELECT * FROM $CFG->prefix$table $select LIMIT 1");
216 function record_exists_sql($sql) {
217 /// Returns true or false depending on whether the specified record exists
218 /// The sql statement is provided as a string.
220     global $db;
222     $rs = $db->Execute($sql);
223     if (empty($rs)) return false;
225     if ( $rs->RecordCount() ) {
226         return true;
227     } else {
228         return false;
229     }
233 function count_records($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") {
234 /// Get all the records and count them
236     global $CFG;
238     if ($field1) {
239         $select = "WHERE $field1 = '$value1'";
240         if ($field2) {
241             $select .= " AND $field2 = '$value2'";
242             if ($field3) {
243                 $select .= " AND $field3 = '$value3'";
244             }
245         }
246     } else {
247         $select = "";
248     }
250     return count_records_sql("SELECT COUNT(*) FROM $CFG->prefix$table $select");
253 function count_records_select($table, $select="") {
254 /// Get all the records and count them
256     global $CFG;
258     if ($select) {
259         $select = "WHERE $select";
260     }
262     return count_records_sql("SELECT COUNT(*) FROM $CFG->prefix$table $select");
266 function count_records_sql($sql) {
267 /// Get all the records and count them
268 /// The sql statement is provided as a string.
270     global $db;
272     $rs = $db->Execute("$sql");
273     if (empty($rs)) return 0;
275     return $rs->fields[0];
281 /// GENERIC FUNCTIONS TO GET, INSERT, OR UPDATE DATA  ///////////////////////////////////
283 function get_record($table, $field1, $value1, $field2="", $value2="", $field3="", $value3="") {
284 /// Get a single record as an object
286     global $CFG;
288     $select = "WHERE $field1 = '$value1'";
290     if ($field2) {
291         $select .= " AND $field2 = '$value2'";
292         if ($field3) {
293             $select .= " AND $field3 = '$value3'";
294         }
295     }
297     return get_record_sql("SELECT * FROM $CFG->prefix$table $select");
300 function get_record_sql($sql) {
301 /// Get a single record as an object
302 /// The sql statement is provided as a string.
304     global $db;
306     $rs = $db->Execute("$sql");
307     if (empty($rs)) return false;
309     if ( $rs->RecordCount() == 1 ) {
310         return (object)$rs->fields;
311     } else {
312         return false;
313     }
316 function get_record_select($table, $select="", $fields="*") {
317 /// Gets one record from a table, as an object
318 /// "select" is a fragment of SQL to define the selection criteria
320     global $CFG;
322     if ($select) {
323         $select = "WHERE $select";
324     }
326     return get_record_sql("SELECT $fields FROM $CFG->prefix$table $select");
330 function get_records($table, $field="", $value="", $sort="", $fields="*") {
331 /// Get a number of records as an array of objects
332 /// Can optionally be sorted eg "time ASC" or "time DESC"
333 /// If "fields" is specified, only those fields are returned
334 /// The "key" is the first column returned, eg usually "id"
336     global $CFG;
338     if ($field) {
339         $select = "WHERE $field = '$value'";
340     } else {
341         $select = "";
342     }
344     if ($sort) {
345         $sort = "ORDER BY $sort";
346     }
348     return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort");
351 function get_records_select($table, $select="", $sort="", $fields="*") {
352 /// Get a number of records as an array of objects
353 /// Can optionally be sorted eg "time ASC" or "time DESC"
354 /// "select" is a fragment of SQL to define the selection criteria
355 /// The "key" is the first column returned, eg usually "id"
357     global $CFG;
359     if ($select) {
360         $select = "WHERE $select";
361     }
363     if ($sort) {
364         $sort = "ORDER BY $sort";
365     }
367     return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort");
371 function get_records_list($table, $field="", $values="", $sort="", $fields="*") {
372 /// Get a number of records as an array of objects
373 /// Differs from get_records() in that the values variable 
374 /// can be a comma-separated list of values eg  "4,5,6,10"
375 /// Can optionally be sorted eg "time ASC" or "time DESC"
376 /// The "key" is the first column returned, eg usually "id"
378     global $CFG;
380     if ($field) {
381         $select = "WHERE $field in ($values)";
382     } else {
383         $select = "";
384     }
386     if ($sort) {
387         $sort = "ORDER BY $sort";
388     }
390     return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort");
395 function get_records_sql($sql) {
396 /// Get a number of records as an array of objects
397 /// The "key" is the first column returned, eg usually "id"
398 /// The sql statement is provided as a string.
400     global $db;
402     $rs = $db->Execute("$sql");
403     if (empty($rs)) return false;
405     if ( $rs->RecordCount() > 0 ) {
406         if ($records = $rs->GetAssoc(true)) {
407             foreach ($records as $key => $record) {
408                 $objects[$key] = (object) $record;
409             }
410             return $objects;
411         } else {
412             return false;
413         }
414     } else {
415         return false;
416     }
419 function get_records_menu($table, $field="", $value="", $sort="", $fields="*") {
420 /// Get a number of records as an array of objects
421 /// Can optionally be sorted eg "time ASC" or "time DESC"
422 /// If "fields" is specified, only those fields are returned
423 /// The "key" is the first column returned, eg usually "id"
425     global $CFG;
427     if ($field) {
428         $select = "WHERE $field = '$value'";
429     } else {
430         $select = "";
431     }
433     if ($sort) {
434         $sort = "ORDER BY $sort";
435     }
437     return get_records_sql_menu("SELECT $fields FROM $CFG->prefix$table $select $sort");
440 function get_records_select_menu($table, $select="", $sort="", $fields="*") {
441 /// Get a number of records as an array of objects
442 /// Can optionally be sorted eg "time ASC" or "time DESC"
443 /// "select" is a fragment of SQL to define the selection criteria
444 /// Returns associative array of first two fields
446     global $CFG;
448     if ($select) {
449         $select = "WHERE $select";
450     }
452     if ($sort) {
453         $sort = "ORDER BY $sort";
454     }
456     return get_records_sql_menu("SELECT $fields FROM $CFG->prefix$table $select $sort");
460 function get_records_sql_menu($sql) {
461 /// Given an SQL select, this function returns an associative 
462 /// array of the first two columns.  This is most useful in 
463 /// combination with the choose_from_menu function to create 
464 /// a form menu.
466     global $db;
468     $rs = $db->Execute("$sql");
469     if (empty($rs)) return false;
471     if ( $rs->RecordCount() > 0 ) {
472         while (!$rs->EOF) {
473             $menu[$rs->fields[0]] = $rs->fields[1];
474             $rs->MoveNext();
475         }
476         return $menu;
477         
478     } else {
479         return false;
480     }
483 function get_field($table, $return, $field, $value) {
484 /// Get a single field from a database record
486     global $db, $CFG;
488     $rs = $db->Execute("SELECT $return FROM $CFG->prefix$table WHERE $field = '$value'");
489     if (empty($rs)) return false;
491     if ( $rs->RecordCount() == 1 ) {
492         return $rs->fields["$return"];
493     } else {
494         return false;
495     }
498 function set_field($table, $newfield, $newvalue, $field, $value) {
499 /// Set a single field in a database record
501     global $db, $CFG;
503     return $db->Execute("UPDATE $CFG->prefix$table SET $newfield = '$newvalue' WHERE $field = '$value'");
507 function delete_records($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") {
508 /// Delete one or more records from a table
510     global $db, $CFG;
512     if ($field1) {
513         $select = "WHERE $field1 = '$value1'";
514         if ($field2) {
515             $select .= " AND $field2 = '$value2'";
516             if ($field3) {
517                 $select .= " AND $field3 = '$value3'";
518             }
519         }
520     } else {
521         $select = "";
522     }
524     return $db->Execute("DELETE FROM $CFG->prefix$table $select");
528 function insert_record($table, $dataobject, $returnid=true) {
529 /// Insert a record into a table and return the "id" field if required
530 /// If the return ID isn't required, then this just reports success as true/false.
531 /// $dataobject is an object containing needed data
533     global $db, $CFG;
535     // Determine all the fields needed
536     if (! $columns = $db->MetaColumns("$CFG->prefix$table")) {
537         return false;
538     }
540     $data = (array)$dataobject;
542     // Pull out data from the dataobject that matches the fields in the table.
543     // If fields are missing or empty, then try to set the defaults explicitly
544     // because some databases (eg PostgreSQL) don't always set them properly
545     foreach ($columns as $column) {
546         if ($column->name <> "id") {
547             if (isset($data[$column->name])) { 
548                 if ((string)$data[$column->name] == "" and !empty($column->has_default) and !empty($column->default_value)) {
549                     $ddd[$column->name] = $column->default_value;
550                 } else {
551                     $ddd[$column->name] = $data[$column->name];
552                 }
553             } else {
554                 if (!empty($column->has_default) and !empty($column->default_value)) {
555                     $ddd[$column->name] = $column->default_value;
556                 } 
557             }
558         }
559     }
562     // Construct SQL queries
563     if (! $numddd = count($ddd)) {
564         return false;
565     }
567     $count = 0;
568     $inscolumns = "";
569     $insvalues = "";
570     $select = "";
572     foreach ($ddd as $key => $value) {
573         if (!is_null($value)){
574             if ($select) {
575                 $inscolumns .= ", ";
576                 $insvalues .= ", ";
577                 $select .= " AND ";
578             }
579             $inscolumns .= "$key";
580             $insvalues .= "'$value'";
581             $select .= "$key = '$value'";
582         }
583     }
585     if (! $rs = $db->Execute("INSERT INTO $CFG->prefix$table ($inscolumns) VALUES ($insvalues)")) {
586         return false;
587     }
589     if ($returnid) {
590         if ($CFG->dbtype == "mysql") { 
591             return $db->Insert_ID();   // ADOdb has stored the ID for us, but it isn't reliable
592         }
593         
594         // Try to pull the record out again to find the id.  This is the most cross-platform method.
595         if ($rs = $db->Execute("SELECT id FROM $CFG->prefix$table WHERE $select")) {
596             if ($rs->RecordCount() == 1) {
597                 return $rs->fields[0];
598             }
599         }
601         return false;
603     } else {
604         return true;
605     }
609 function update_record($table, $dataobject) {
610 /// Update a record in a table
611 /// $dataobject is an object containing needed data
612 /// Relies on $dataobject having a variable "id" to 
613 /// specify the record to update
615     global $db, $CFG;
617     if (! isset($dataobject->id) ) {
618         return false;
619     }
621     // Determine all the fields in the table
622     if (!$columns = $db->MetaColumns("$CFG->prefix$table")) {
623         return false;
624     }
625     $data = (array)$dataobject;
627     // Pull out data matching these fields
628     foreach ($columns as $column) {
629         if ($column->name <> "id" and isset($data[$column->name]) ) {
630             $ddd[$column->name] = $data[$column->name];
631         }
632     }
634     // Construct SQL queries
635     $numddd = count($ddd);
636     $count = 0;
637     $update = "";
639     foreach ($ddd as $key => $value) {
640         $count++;
641         $update .= "$key = '$value'";
642         if ($count < $numddd) {
643             $update .= ", ";
644         }
645     }
647     if ($rs = $db->Execute("UPDATE $CFG->prefix$table SET $update WHERE id = '$dataobject->id'")) {
648         return true;
649     } else {
650         return false;
651     }
657 /// USER DATABASE ////////////////////////////////////////////////
659 function get_user_info_from_db($field, $value) {
660 /// Get a complete user record, which includes all the info 
661 /// in the user record, as well as membership information
662 /// Suitable for setting as $USER session cookie.
664     if (!$field or !$value) {
665         return false;
666     }
668     if (! $user = get_record_select("user", "$field = '$value' AND deleted <> '1'")) {
669         return false;
670     }
672     // Add membership information
674     if ($site = get_site()) { // Everyone is always a member of the top course
675         $user->student[$site->id] = true;
676     }
678     if ($students = get_records("user_students", "userid", $user->id)) {
679         foreach ($students as $student) {
680             $user->student[$student->course] = true;
681         }
682     }
684     if ($teachers = get_records("user_teachers", "userid", $user->id)) {
685         foreach ($teachers as $teacher) {
686             $user->teacher[$teacher->course] = true;
687         }
688     }
690     if ($admins = get_records("user_admins", "userid", $user->id)) {
691         foreach ($admins as $admin) {
692             $user->admin = true;
693             break;
694         }
695     }
697     return $user;
700 function update_user_in_db() {
701 /// Updates user record to record their last access
703    global $db, $USER, $REMOTE_ADDR, $CFG;
705    if (!isset($USER->id)) 
706        return false;
708    $timenow = time();
709    if ($db->Execute("UPDATE {$CFG->prefix}user SET lastIP='$REMOTE_ADDR', lastaccess='$timenow' 
710                      WHERE id = '$USER->id' ")) {
711        return true;
712    } else {
713        return false;
714    }
718 function adminlogin($username, $md5password) {
719 /// Does this username and password specify a valid admin user?
721     global $CFG;
723     return record_exists_sql("SELECT u.id 
724                                 FROM {$CFG->prefix}user u, 
725                                      {$CFG->prefix}user_admins a 
726                               WHERE u.id = a.userid 
727                                 AND u.username = '$username' 
728                                 AND u.password = '$md5password'");
732 function get_site () {
733 /// Returns $course object of the top-level site.
735     if ( $course = get_record("course", "category", 0)) {
736         return $course;
737     } else {
738         return false;
739     }
743 function get_courses($category=0, $sort="fullname ASC") {
744 /// Returns list of courses
746     if ($category > 0) {          // Return all courses in one category
747         return get_records("course", "category", $category, $sort);
749     } else if ($category < 0) {   // Return all courses, even the site
750         return get_records("course", "", "", $sort);
752     } else {                      // Return all courses, except site
753         return get_records_select("course", "category > 0", $sort);
754     }
757 function get_categories() {
758     return get_records("course_categories", "", "", "name");
762 function get_guest() {
763     return get_user_info_from_db("username", "guest");
767 function get_admin () {
768 /// Returns $user object of the main admin user
770     global $CFG;
772     if ( $admins = get_admins() ) {
773         foreach ($admins as $admin) {
774             return $admin;   // ie the first one 
775         }
776     } else {
777         return false;
778     }
781 function get_admins() {
782 /// Returns list of all admins
784     global $CFG;
786     return get_records_sql("SELECT u.* 
787                               FROM {$CFG->prefix}user u, 
788                                    {$CFG->prefix}user_admins a
789                              WHERE a.userid = u.id
790                              ORDER BY u.id ASC");
793 function get_creators() {
794 /// Returns list of all admins
796     global $CFG;
798     return get_records_sql("SELECT u.*
799                               FROM {$CFG->prefix}user u,
800                                    {$CFG->prefix}user_coursecreators a
801                              WHERE a.userid = u.id
802                              ORDER BY u.id ASC");
805 function get_teacher($courseid) {
806 /// Returns $user object of the main teacher for a course
808     global $CFG;
810     if ( $teachers = get_course_teachers($courseid, "t.authority ASC")) {
811         foreach ($teachers as $teacher) {
812             if ($teacher->authority) {
813                 return $teacher;   // the highest authority teacher
814             }
815         }
816     } else {
817         return false;
818     }
821 function get_course_students($courseid, $sort="u.lastaccess DESC") {
822 /// Returns list of all students in this course
823 /// if courseid = 0 then return ALL students in all courses
825     global $CFG;
827     return get_records_sql("SELECT u.* FROM {$CFG->prefix}user u, {$CFG->prefix}user_students s
828                             WHERE s.course = '$courseid' AND s.userid = u.id AND u.deleted = '0'
829                             ORDER BY $sort");
832 function get_course_teachers($courseid, $sort="t.authority ASC") {
833 /// Returns list of all teachers in this course
834 /// if courseid = 0 then return ALL teachers in all courses
836     global $CFG;
838     return get_records_sql("SELECT u.*,t.authority,t.role FROM {$CFG->prefix}user u, {$CFG->prefix}user_teachers t
839                             WHERE t.course = '$courseid' AND t.userid = u.id AND u.deleted = '0'
840                             ORDER BY $sort");
843 function get_course_users($courseid, $sort="u.lastaccess DESC") {
844 /// Using this method because the direct SQL just would not always work!
846     $teachers = get_course_teachers($courseid, $sort);
847     $students = get_course_students($courseid, $sort);
849     if ($teachers and $students) {
850         return array_merge($teachers, $students);
851     } else if ($teachers) {
852         return $teachers;
853     } else {
854         return $students;
855     }
857 ///    return get_records_sql("SELECT u.* FROM user u, user_students s, user_teachers t
858 ///                            WHERE (s.course = '$courseid' AND s.userid = u.id) OR 
859 ///                                  (t.course = '$courseid' AND t.userid = u.id)
860 ///                            ORDER BY $sort");
863 function get_site_users($sort="u.lastaccess DESC") {
864 /// Returns a list of all active users who are enrolled 
865 /// or teaching in courses on this server
867     global $CFG;
869     return get_records_sql("SELECT u.* FROM {$CFG->prefix}user u, 
870                                             {$CFG->prefix}user_students s, 
871                                             {$CFG->prefix}user_teachers t
872                             WHERE s.userid = u.id 
873                                OR t.userid = u.id
874                             GROUP BY u.id ORDER BY $sort");
877 function get_users_search($search, $sort="u.firstname ASC") {
878     global $CFG;
880     return get_records_sql("SELECT * from {$CFG->prefix}user 
881                              WHERE confirmed = 1 
882                                AND deleted = 0
883                                AND (firstname LIKE '%$search%' OR 
884                                     lastname LIKE '%$search%' OR 
885                                     email LIKE '%$search%')
886                                AND username <> 'guest' 
887                                AND username <> 'changeme'");
891 function get_users_count($search="") {
893     if ($search) {
894         $search = " AND (firstname LIKE '%$search%'
895                      OR lastname LIKE '%$search%'
896                      OR email LIKE '%$search%') ";
897     }
899     return count_records_select("user", "username <> 'guest' AND deleted <> 1 $search");
902 function get_users_listing($sort, $dir="ASC", $page=1, $recordsperpage=20, $search="") {
903     global $CFG;
905     switch ($CFG->dbtype) {
906         case "mysql":
907              $limit = "LIMIT $page,$recordsperpage";
908              break;
909         case "postgres7":
910              $limit = "LIMIT $recordsperpage OFFSET ".($page * $recordsperpage);
911              break;
912         default: 
913              $limit = "LIMIT $recordsperpage,$page";
914     }
916     if ($search) {
917         $search = " AND (firstname LIKE '%$search%'
918                      OR lastname LIKE '%$search%'
919                      OR email LIKE '%$search%') ";
920     }
922     return get_records_sql("SELECT id, username, email, firstname, lastname, city, country, lastaccess  
923                               FROM {$CFG->prefix}user 
924                              WHERE username <> 'guest' 
925                                AND deleted <> '1' $search
926                           ORDER BY $sort $dir $limit");
930 function get_users_confirmed() {
931     global $CFG;
932     return get_records_sql("SELECT * 
933                               FROM {$CFG->prefix}user 
934                              WHERE confirmed = 1 
935                                AND deleted = 0
936                                AND username <> 'guest' 
937                                AND username <> 'changeme'");
941 function get_users_unconfirmed($cutofftime=2000000000) {
942     global $CFG;
943     return get_records_sql("SELECT * 
944                              FROM {$CFG->prefix}user 
945                             WHERE confirmed = 0
946                               AND firstaccess > 0 
947                               AND firstaccess < '$cutofftime'");
951 function get_users_longtimenosee($cutofftime) {
952     global $CFG;
954     $db->debug = true;
955     return get_records_sql("SELECT u.* 
956                               FROM {$CFG->prefix}user u, 
957                                    {$CFG->prefix}user_students s
958                              WHERE u.lastaccess > '0' 
959                                AND u.lastaccess < '$cutofftime' 
960                                AND u.id = s.userid
961                           GROUP BY u.id");
966 /// MODULE FUNCTIONS /////////////////////////////////////////////////
968 function get_course_mods($courseid) {
969 /// Just gets a raw list of all modules in a course
970     global $CFG;
972     return get_records_sql("SELECT cm.*, m.name as modname
973                             FROM {$CFG->prefix}modules m, {$CFG->prefix}course_modules cm
974                             WHERE cm.course = '$courseid' 
975                             AND cm.deleted = '0'
976                             AND cm.module = m.id ");
979 function get_coursemodule_from_instance($modulename, $instance, $courseid) {
980 /// Given an instance of a module, finds the coursemodule description
982     global $CFG;
984     return get_record_sql("SELECT cm.*, m.name
985                            FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}modules md, {$CFG->prefix}$modulename m 
986                            WHERE cm.course = '$courseid' AND 
987                                  cm.deleted = '0' AND
988                                  cm.instance = m.id AND 
989                                  md.name = '$modulename' AND 
990                                  md.id = cm.module AND
991                                  m.id = '$instance'");
995 function get_all_instances_in_course($modulename, $courseid, $sort="cw.section") {
996 /// Returns an array of all the active instances of a particular
997 /// module in a given course.   Returns false on any errors.
999     global $CFG;
1001     return get_records_sql("SELECT m.*,cw.section,cm.id as coursemodule 
1002                             FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}course_sections cw, 
1003                                  {$CFG->prefix}modules md, {$CFG->prefix}$modulename m 
1004                             WHERE cm.course = '$courseid' AND 
1005                                   cm.instance = m.id AND 
1006                                   cm.deleted = '0' AND
1007                                   cm.section = cw.id AND 
1008                                   md.name = '$modulename' AND 
1009                                   md.id = cm.module
1010                             ORDER BY $sort");
1018 /// LOG FUNCTIONS /////////////////////////////////////////////////////
1021 function add_to_log($course, $module, $action, $url="", $info="") {
1022 /// Add an entry to the log table.  These are "action" focussed rather
1023 /// than web server hits, and provide a way to easily reconstruct what 
1024 /// any particular student has been doing.
1025 ///
1026 /// course = the course id
1027 /// module = forum, journal, resource, course, user etc
1028 /// action = view, edit, post (often but not always the same as the file.php)
1029 /// url    = the file and parameters used to see the results of the action
1030 /// info   = additional description information 
1032     global $db, $CFG, $USER, $REMOTE_ADDR;
1034     if (isset($USER->realuser)) {  // Don't log
1035         return;
1036     }
1038     $userid = empty($USER->id) ? "" : $USER->id;
1040     $timenow = time();
1041     $info = addslashes($info);
1043     $result = $db->Execute("INSERT INTO {$CFG->prefix}log (time,
1044                                         userid,
1045                                         course,
1046                                         ip,
1047                                         module,
1048                                         action,
1049                                         url,
1050                                         info)
1051                              VALUES ('$timenow',
1052                                         '$userid',
1053                                         '$course',
1054                                         '$REMOTE_ADDR',
1055                                         '$module',
1056                                         '$action',
1057                                         '$url',
1058                                         '$info')");
1060     if (!$result and ($CFG->debug > 7)) {
1061         echo "<P>Error: Could not insert a new entry to the Moodle log</P>";  // Don't throw an error
1062     }    
1066 function get_logs($select, $order) {
1067     global $CFG;
1069     return get_records_sql("SELECT l.*, u.firstname, u.lastname, u.picture 
1070                               FROM {$CFG->prefix}log l, 
1071                                    {$CFG->prefix}user u 
1072                                    $select $order");
1075 function get_logs_usercourse($userid, $courseid, $coursestart) {
1076     global $CFG;
1078     return get_records_sql("SELECT floor((`time` - $coursestart)/86400) as day, count(*) as num 
1079                             FROM {$CFG->prefix}log 
1080                            WHERE userid = '$userid' 
1081                              AND course = '$courseid'
1082                              AND `time` > '$coursestart'
1083                         GROUP BY day ");
1086 function get_logs_userday($userid, $courseid, $daystart) {
1087     global $CFG;
1089     return get_records_sql("SELECT floor((`time` - $daystart)/3600) as hour, count(*) as num
1090                             FROM {$CFG->prefix}log
1091                            WHERE userid = '$userid' 
1092                              AND course = '$courseid'
1093                              AND `time` > '$daystart'
1094                         GROUP BY hour ");
1097 /// GENERAL HELPFUL THINGS  ///////////////////////////////////
1099 function print_object($object) {
1100 /// Mostly just for debugging
1102     echo "<PRE>";
1103     print_r($object);
1104     echo "</PRE>";
1109 // vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140:
1110 ?>