Added a search form to the "edit users" admin page yay!
[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
824     global $CFG;
826     return get_records_sql("SELECT u.* FROM {$CFG->prefix}user u, {$CFG->prefix}user_students s
827                             WHERE s.course = '$courseid' AND s.userid = u.id AND u.deleted = '0'
828                             ORDER BY $sort");
831 function get_course_teachers($courseid, $sort="t.authority ASC") {
832 /// Returns list of all teachers in this course
834     global $CFG;
836     return get_records_sql("SELECT u.*,t.authority,t.role FROM {$CFG->prefix}user u, {$CFG->prefix}user_teachers t
837                             WHERE t.course = '$courseid' AND t.userid = u.id AND u.deleted = '0'
838                             ORDER BY $sort");
841 function get_course_users($courseid, $sort="u.lastaccess DESC") {
842 /// Using this method because the direct SQL just would not always work!
844     $teachers = get_course_teachers($courseid, $sort);
845     $students = get_course_students($courseid, $sort);
847     if ($teachers and $students) {
848         return array_merge($teachers, $students);
849     } else if ($teachers) {
850         return $teachers;
851     } else {
852         return $students;
853     }
855 ///    return get_records_sql("SELECT u.* FROM user u, user_students s, user_teachers t
856 ///                            WHERE (s.course = '$courseid' AND s.userid = u.id) OR 
857 ///                                  (t.course = '$courseid' AND t.userid = u.id)
858 ///                            ORDER BY $sort");
862 function get_users_search($search, $sort="u.firstname ASC") {
863     global $CFG;
865     return get_records_sql("SELECT * from {$CFG->prefix}user 
866                              WHERE confirmed = 1 
867                                AND deleted = 0
868                                AND (firstname LIKE '%$search%' OR 
869                                     lastname LIKE '%$search%' OR 
870                                     email LIKE '%$search%')
871                                AND username <> 'guest' 
872                                AND username <> 'changeme'");
876 function get_users_count() {
877     return count_records_select("user", "username <> 'guest' AND deleted <> 1");
880 function get_users_listing($sort, $dir="ASC", $page=1, $recordsperpage=20, $search="") {
881     global $CFG;
883     switch ($CFG->dbtype) {
884         case "mysql":
885              $limit = "LIMIT $page,$recordsperpage";
886              break;
887         case "postgres7":
888              $limit = "LIMIT $recordsperpage OFFSET ".($page * $recordsperpage);
889              break;
890         default: 
891              $limit = "LIMIT $recordsperpage,$page";
892     }
894     if ($search) {
895         $search = " AND (firstname LIKE '%$search%'
896                      OR lastname LIKE '%$search%'
897                      OR email LIKE '%$search%') ";
898     }
900     return get_records_sql("SELECT id, username, email, firstname, lastname, city, country, lastaccess  
901                               FROM {$CFG->prefix}user 
902                              WHERE username <> 'guest' 
903                                AND deleted <> '1' $search
904                           ORDER BY $sort $dir $limit");
908 function get_users_confirmed() {
909     global $CFG;
910     return get_records_sql("SELECT * 
911                               FROM {$CFG->prefix}user 
912                              WHERE confirmed = 1 
913                                AND deleted = 0
914                                AND username <> 'guest' 
915                                AND username <> 'changeme'");
919 function get_users_unconfirmed($cutofftime=2000000000) {
920     global $CFG;
921     return get_records_sql("SELECT * 
922                              FROM {$CFG->prefix}user 
923                             WHERE confirmed = 0
924                               AND firstaccess > 0 
925                               AND firstaccess < '$cutofftime'");
929 function get_users_longtimenosee($cutofftime) {
930     global $CFG;
932     $db->debug = true;
933     return get_records_sql("SELECT u.* 
934                               FROM {$CFG->prefix}user u, 
935                                    {$CFG->prefix}user_students s
936                              WHERE u.lastaccess > '0' 
937                                AND u.lastaccess < '$cutofftime' 
938                                AND u.id = s.userid
939                           GROUP BY u.id");
944 /// MODULE FUNCTIONS /////////////////////////////////////////////////
946 function get_course_mods($courseid) {
947 /// Just gets a raw list of all modules in a course
948     global $CFG;
950     return get_records_sql("SELECT cm.*, m.name as modname
951                             FROM {$CFG->prefix}modules m, {$CFG->prefix}course_modules cm
952                             WHERE cm.course = '$courseid' 
953                             AND cm.deleted = '0'
954                             AND cm.module = m.id ");
957 function get_coursemodule_from_instance($modulename, $instance, $courseid) {
958 /// Given an instance of a module, finds the coursemodule description
960     global $CFG;
962     return get_record_sql("SELECT cm.*, m.name
963                            FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}modules md, {$CFG->prefix}$modulename m 
964                            WHERE cm.course = '$courseid' AND 
965                                  cm.deleted = '0' AND
966                                  cm.instance = m.id AND 
967                                  md.name = '$modulename' AND 
968                                  md.id = cm.module AND
969                                  m.id = '$instance'");
973 function get_all_instances_in_course($modulename, $courseid, $sort="cw.section") {
974 /// Returns an array of all the active instances of a particular
975 /// module in a given course.   Returns false on any errors.
977     global $CFG;
979     return get_records_sql("SELECT m.*,cw.section,cm.id as coursemodule 
980                             FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}course_sections cw, 
981                                  {$CFG->prefix}modules md, {$CFG->prefix}$modulename m 
982                             WHERE cm.course = '$courseid' AND 
983                                   cm.instance = m.id AND 
984                                   cm.deleted = '0' AND
985                                   cm.section = cw.id AND 
986                                   md.name = '$modulename' AND 
987                                   md.id = cm.module
988                             ORDER BY $sort");
996 /// LOG FUNCTIONS /////////////////////////////////////////////////////
999 function add_to_log($course, $module, $action, $url="", $info="") {
1000 /// Add an entry to the log table.  These are "action" focussed rather
1001 /// than web server hits, and provide a way to easily reconstruct what 
1002 /// any particular student has been doing.
1003 ///
1004 /// course = the course id
1005 /// module = forum, journal, resource, course, user etc
1006 /// action = view, edit, post (often but not always the same as the file.php)
1007 /// url    = the file and parameters used to see the results of the action
1008 /// info   = additional description information 
1010     global $db, $CFG, $USER, $REMOTE_ADDR;
1012     if (isset($USER->realuser)) {  // Don't log
1013         return;
1014     }
1016     $userid = empty($USER->id) ? "" : $USER->id;
1018     $timenow = time();
1019     $info = addslashes($info);
1021     $result = $db->Execute("INSERT INTO {$CFG->prefix}log (time,
1022                                         userid,
1023                                         course,
1024                                         ip,
1025                                         module,
1026                                         action,
1027                                         url,
1028                                         info)
1029                              VALUES ('$timenow',
1030                                         '$userid',
1031                                         '$course',
1032                                         '$REMOTE_ADDR',
1033                                         '$module',
1034                                         '$action',
1035                                         '$url',
1036                                         '$info')");
1038     if (!$result and ($CFG->debug > 7)) {
1039         echo "<P>Error: Could not insert a new entry to the Moodle log</P>";  // Don't throw an error
1040     }    
1044 function get_logs($select, $order) {
1045     global $CFG;
1047     return get_records_sql("SELECT l.*, u.firstname, u.lastname, u.picture 
1048                               FROM {$CFG->prefix}log l, 
1049                                    {$CFG->prefix}user u 
1050                                    $select $order");
1053 function get_logs_usercourse($userid, $courseid, $coursestart) {
1054     global $CFG;
1056     return get_records_sql("SELECT floor((`time` - $coursestart)/86400) as day, count(*) as num 
1057                             FROM {$CFG->prefix}log 
1058                            WHERE userid = '$userid' 
1059                              AND course = '$courseid'
1060                              AND `time` > '$coursestart'
1061                         GROUP BY day ");
1064 function get_logs_userday($userid, $courseid, $daystart) {
1065     global $CFG;
1067     return get_records_sql("SELECT floor((`time` - $daystart)/3600) as hour, count(*) as num
1068                             FROM {$CFG->prefix}log
1069                            WHERE userid = '$userid' 
1070                              AND course = '$courseid'
1071                              AND `time` > '$daystart'
1072                         GROUP BY hour ");
1075 /// GENERAL HELPFUL THINGS  ///////////////////////////////////
1077 function print_object($object) {
1078 /// Mostly just for debugging
1080     echo "<PRE>";
1081     print_r($object);
1082     echo "</PRE>";
1087 // vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140:
1088 ?>