From 044a8fbfaa7f8aa6de9d1751f08eb611d20c8854 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Mon, 27 Feb 2017 12:52:47 -0500 Subject: [PATCH 01/10] Add experiments exploring the new logging structure for moodle. This is a (kind of) stable stopping point. --- lib.php | 248 ++++++++++++++++++++++++++++++++++++++++----------- locallib.php | 4 +- version.php | 4 +- 3 files changed, 199 insertions(+), 57 deletions(-) diff --git a/lib.php b/lib.php index 289100a..16ad038 100644 --- a/lib.php +++ b/lib.php @@ -498,7 +498,9 @@ function wwassignment_cron() { //wwassignment_update_grades(null,0); //try { // try didn't work on some php systems -- leave it out. wwassignment_update_dirty_sets(); + mtrace("wwassignment cron"); debugLog("End wwassignment_cron"); + mtrace("wwassignment cron"); return true; } @@ -517,69 +519,209 @@ function wwassignment_cron() { // // $modinfo = get_fast_modinfo($course); // - + +// function report_log_userday($userid, $courseid, $daystart, $logreader = '') { +// global $DB; +// $logmanager = get_log_manager(); +// $readers = $logmanager->get_readers(); +// if (empty($logreader)) { +// $reader = reset($readers); +// } else { +// $reader = $readers[$logreader]; +// } +// +// // If reader is not a sql_internal_table_reader and not legacy store then return. +// if (!($reader instanceof \core\log\sql_internal_table_reader) && !($reader instanceof logstore_legacy\log\store)) { +// return array(); +// } +// +// $daystart = (int)$daystart; // Note: unfortunately pg complains if you use name parameter or column alias in GROUP BY. +// +// if ($reader instanceof logstore_legacy\log\store) { +// $logtable = 'log'; +// $timefield = 'time'; +// $coursefield = 'course'; +// // Anonymous actions are never logged in legacy log. +// $nonanonymous = ''; +// } else { +// $logtable = $reader->get_internal_log_table_name(); +// $timefield = 'timecreated'; +// $coursefield = 'courseid'; +// $nonanonymous = 'AND anonymous = 0'; +// } +// $params = array('userid' => $userid); +// +// $courseselect = ''; +// if ($courseid) { +// $courseselect = "AND $coursefield = :courseid"; +// $params['courseid'] = $courseid; +// } +// return $DB->get_records_sql("SELECT FLOOR(($timefield - $daystart)/" . HOURSECS . ") AS hour, COUNT(*) AS num +// FROM {" . $logtable . "} +// WHERE userid = :userid +// AND $timefield > $daystart $courseselect $nonanonymous +// GROUP BY FLOOR(($timefield - $daystart)/" . HOURSECS . ") ", $params); +// } +// +// target = course_module +// objecttable = wwassignment +// id = +// timecreated +// courseid + function wwassignment_update_dirty_sets() { // update grades for all instances which have been modified since last cronjob global $CFG,$DB; + global $CFG; +require_once($CFG->dirroot.'/course/lib.php'); +require_once($CFG->dirroot.'/report/log/locallib.php'); +require_once($CFG->libdir.'/adminlib.php'); +require_once($CFG->dirroot.'/lib/tablelib.php'); + $timenow = time(); $lastcron = $DB->get_field("modules","lastcron",array( "name"=>"wwassignment" )); -// error_log ("lastcron is $lastcron and time now is $timenow"); - - //error_log ("sql string = $sql"); - // Could we speed this up by getting all of the log records pertaining to webwork in one go? - // Or perhaps just the log records which have occured after the lastcron date - // Then create a hash with wwassignment->id => timemodified - // means just one database lookup - $counter = 0; - $logRecords = get_logs("l.module LIKE \"wwassignment\" AND l.time >$lastcron ", null, "l.time ASC", $counter); - $wwmodtimes=array(); - foreach ($logRecords as $record) { - $wwmodtimes[$wwid =$record->info] = $record->time; + $lastcron = 1483202964; # so we get some examples + debugLog("1. lastcron is $lastcron and time now is $timenow"); + //////////////////// + $logreader=''; + $logmanager = get_log_manager(); + $readers = $logmanager->get_readers(); + if (empty($logreader)) { + $reader = reset($readers); + } else { + $reader = $readers[$logreader]; + } + debugLog("reader is not yet known 4"); + if ($reader instanceof \core\log\sql_internal_table_reader) { + debugLog("reader is instance of \core\log\sql_internal_table_reader" ); } - // Create an array with the wwid values - $idValues= implode(",", array_keys($wwmodtimes) ); - list($usql,$params) = $DB->get_in_or_equal($idValues); + // If reader is not a sql_internal_table_reader and not legacy store then return. + if (!($reader instanceof \core\log\sql_internal_table_reader) && !($reader instanceof logstore_legacy\log\store)) { + //return array(); + mtrace("don't have access to the right kind of logs"); + debugLog("bad logs "); + } + debugLog("continue processing"); +// $daystart = (int)$lastcron; // Note: unfortunately pg complains if you use name parameter or column alias in GROUP BY. +// + if ($reader instanceof logstore_legacy\log\store) { + $logtable = 'log'; + $timefield = 'time'; + $coursefield = 'course'; + // Anonymous actions are never logged in legacy log. + $nonanonymous = ''; + } else { + $logtable = $reader->get_internal_log_table_name(); + $timefield = 'timecreated'; + $coursefield = 'courseid'; + $nonanonymous = 'AND anonymous = 0'; + } - //error_log("values string $idValues"); - //error_log("last modification times".print_r($wwmodtimes,true)); - - - $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid, cm.id as wwinstanceid " . - "FROM {wwassignment} a, {course_modules} cm, {modules} m WHERE m.name = 'wwassignment' " . - "AND m.id=cm.module AND cm.instance=a.id AND a.id $usql"; +// +// $courseselect = ''; +// if ($courseid) { +// $courseselect = "AND $coursefield = :courseid"; +// $params['courseid'] = $courseid; +// } + + $params['module_type'] = 'course_module'; + $params['wwassignment'] = 'wwassignment'; + debugLog("using the log table $logtable"); +// +// //$daystart = (int)$daystart; // Note: unfortunately pg complains if you use name parameter or column alias in GROUP BY. +// //////////////// +// //error_log ("sql string = $sql"); +// // Could we speed this up by getting all of the log records pertaining to webwork in one go? +// // Or perhaps just the log records which have occured after the lastcron date +// // Then create a hash with wwassignment->id => timemodified +// // means just one database lookup +// $counter = 0; +// // this is most likely what needs to be replaced +// +// +// // $logRecords = get_logs("l.module LIKE \"wwassignment\" AND l.time >$lastcron ", null, "l.time ASC", $counter,''); + $logRecords = $DB->get_records_sql("SELECT $timefield AS time, COUNT(*) AS num, + $coursefield AS courseid, target AS target, + objecttable AS module, + id AS eventid + FROM {" . $logtable . "} + WHERE $timefield > $lastcron + AND target = :module_type + AND objecttable = :wwassignment + GROUP BY $timefield", $params); + $number_of_log_records = count($logRecords); + debugLog("number of logRecords $number_of_log_records"); + //debugLog(print_r($logRecords,true)); - $sql3 = "SELECT a.* FROM {wwassignment} a WHERE a.id $usql"; + mtrace("2. last CRON is $lastcron, then TIMENOW $timenow"); - //error_log("last modification times".print_r($wwmodificationtime,true)); - if ($rs = $DB->get_recordset_sql($sql,$params)) { - foreach ( $rs as $wwassignment ) { - if (!$wwassignment->cmidnumber) { // is this ever needed? - $wwassignment->cmidnumber =_wwassignment_cmid() ; - } - $wwassignment->timemodified = $wwmodtimes[$wwassignment->id]; - if ($wwassignment->timemodified > $lastcron) { -// error_log("instance needs update. timemodified ".$wwassignment->timemodified. -// ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. -// ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); - if ($wwassignment->grade != 0) { - wwassignment_update_grades($wwassignment); - } else { - wwassignment_grade_item_update($wwassignment); - } - // refresh events for this assignment - _wwassignment_refresh_event($wwassignment); - - } else { -// error_log("no update needed. timemodified ".$wwassignment->timemodified. -// ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. -// ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); - } - - } - $rs->close(); - } -// error_log("done with updating dirty sets"); + + $wwmodtimes=array(); + foreach ($logRecords as $record) { + debugLog("record info ".($record->courseid)); + debugLog("record time ".($record->time)); + $wwmodtimes[$record->courseid] = $record->time; + } +// +// // Create an array with the wwid values +// $idValues= implode(",", array_keys($wwmodtimes) ); +// //list($insql,$inparams) = $DB->get_in_or_equal($idValues,SQL_PARAMS_NAMED); + $arraykeys = array_keys($wwmodtimes); +// //debugLog("array_keys ".print_r($arraykeys,true)); + list($insql,$inparams) = $DB->get_in_or_equal($arraykeys,SQL_PARAMS_NAMED); +// //list($insql, $inparams) = $DB->get_in_or_equal($wwmodtimes,SQL_PARAMS_NAMED); +// debugLog("values string: $idValues"); +// debugLog("last modification times".print_r($wwmodtimes,true)); + debugLog("insql ".print_r($insql,true)); + debugLog("array values".print_r(array_values($arraykeys),true)); + debugLog("inparams ".print_r($inparams, true)); + + $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid, + cm.id as wwinstanceid " . + "FROM {wwassignment} a, + {course_modules} cm, + {modules} m + WHERE m.name = 'wwassignment' + AND m.id=cm.module + AND cm.instance=a.id + AND a.id $insql"; + debugLog("sql is $sql"); +// $sql3 = "SELECT a.* FROM {wwassignment} a WHERE a.id $usql"; +// +// +// if ($rs = $DB->get_recordset_sql($sql,$inparams)) { +// debugLog("record sets are ".print_r($rs, true)); +// foreach ( $rs as $wwassignment ) { +// debugLog("one record set ".print_r($wwassignment, true)); +// if (!$wwassignment->cmidnumber) { // is this ever needed? +// $wwassignment->cmidnumber =_wwassignment_cmid() ; +// } +// $wwassignment->timemodified = $wwmodtimes[$wwassignment->id]; +// if ($wwassignment->timemodified > $lastcron) { +// debugLog("instance needs update. timemodified ".$wwassignment->timemodified. +// ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. +// ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); +// if ($wwassignment->grade != 0) { +// debugLog("update entire set ".print_r($wwassignment, true ) ); +// //wwassignment_update_grades($wwassignment); +// } else { +// debugLog("update one item in set ".print_r($wwassignment, true) ); +// //wwassignment_grade_item_update($wwassignment); +// } +// // // refresh events for this assignment +// // _wwassignment_refresh_event($wwassignment); +// // +// } else { +// debugLog("no update needed. timemodified ".$wwassignment->timemodified. +// ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. +// ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); +// } +// +// } +// $rs->close(); +// } + debugLog("done with updating dirty sets"); return(true); } diff --git a/locallib.php b/locallib.php index d81d1be..c14f018 100644 --- a/locallib.php +++ b/locallib.php @@ -3,8 +3,8 @@ #require_once("$CFG->libdir/soap/nusoap.php"); require_once("$CFG->libdir/soaplib.php"); -define('WWASSIGNMENT_DEBUG',0); -// define('WWASSIGNMENT_DEBUG',1); +//define('WWASSIGNMENT_DEBUG',0); + define('WWASSIGNMENT_DEBUG',1); ////////////////////////////////////////////////////////////////// diff --git a/version.php b/version.php index 309cab1..87a8dbc 100644 --- a/version.php +++ b/version.php @@ -24,9 +24,9 @@ // 3.0+ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2015030916; // The current module version (Date: YYYYMMDDXX) +$plugin->version = 2015030918; // The current module version (Date: YYYYMMDDXX) $plugin->requires = 2014110400; // Requires this Moodle version -$plugin->cron = 300; // Period for cron to check this module (secs) -- every 5 minutes +$plugin->cron = 10; // Period for cron to check this module (secs) -- every 5 minutes $plugin->component = 'mod_wwassignment'; $plugin->maturity = MATURITY_STABLE; From 6b56fb34a152b8e03e3c85c943758651043dabbf Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Mon, 6 Mar 2017 06:31:43 -0500 Subject: [PATCH 02/10] =?UTF-8?q?Plant=20piton=20here=20=E2=80=94=20some?= =?UTF-8?q?=20things=20are=20working=20but=20we=E2=80=99re=20still=20not?= =?UTF-8?q?=20fetching=20all=20the=20grades.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib.php | 275 ++++++++++++++++++++++++++++++++++++++------------- locallib.php | 12 ++- 2 files changed, 211 insertions(+), 76 deletions(-) diff --git a/lib.php b/lib.php index 16ad038..abedb28 100644 --- a/lib.php +++ b/lib.php @@ -32,7 +32,18 @@ // wwassignment_update_grade_item(wwassignment) -- just updates grade_item table // wwassignment_update_grade_item(wwassignment, grades) updates grade_item table and grade_grades table //////////////////////////////////////////////////////////////// + + function grade_update($source, $courseid, $itemtype, $itemmodule, + $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL) { + error_log("function grade_update called but not implemented") + } +/** + * Refetches data from all course activities + * @param int $courseid + * @param string $modname + * @return success + */ //////////////////////////////////////////////////////////////// @@ -165,28 +176,28 @@ function wwassignment_delete_instance($wwassignmentid) { return $result; } - /** gradebook upgrades +/** gradebook upgrades * add xxx_update_grades() function into mod/xxx/lib.php -� � * add xxx_grade_item_update() function into mod/xxx/lib.php -� � * patch xxx_update_instance(), xxx_insert_instance()? xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update() -� � * patch all places of code that change grade values to call xxx_update_grades() -� � * patch code that displays grades to students to use final grades from the gradebook� - **/ + * add xxx_grade_item_update() function into mod/xxx/lib.php + * patch xxx_update_instance(), xxx_insert_instance()? xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update() + * patch all places of code that change grade values to call xxx_update_grades() + * patch code that displays grades to students to use final grades from the gradebook� +**/ /** - * Return grade for given user or all users. + * Return, for a given homework assignment, the grade for a single user or for all users. * * @param int $assignmentid id of assignment * @param int $userid optional user id, 0 means all users - * @return array array of grades, false if none + * @return a hash of studentid=>grade values , false if none */ function wwassignment_get_user_grades($wwassignment,$userid=0) { debugLog("Begin wwassignment_get_user_grades"); //debugLog("inputs -- wwassignment" . print_r($wwassignment,true)); - //debugLog("userid = $userid"); + debugLog("userid = $userid"); require_once("locallib.php"); @@ -209,19 +220,28 @@ function wwassignment_get_user_grades($wwassignment,$userid=0) { array_push($usernamearray,$student->username); } } + // get data from WeBWorK + debugLog("calling 'grade_users_sets'"); + debugLog("course $wwcoursename set $wwsetname"); + debugLog("students ".print_r($usernamearray,true)); + $gradearray = $wwclient->grade_users_sets($wwcoursename, + $usernamearray,$wwsetname); - $gradearray = $wwclient->grade_users_sets($wwcoursename,$usernamearray,$wwsetname); // FIXME? return key/value pairs instead? // returns an array of grades -- the number of questions answered correctly? // debugLog("usernamearray " . print_r($usernamearray, true)); // debugLog("grades($wwcoursename,usernamearray,$wwsetname) = " . print_r($gradearray, true)); // model for output of grades + // FIXME? return key/value pairs instead? in grade_users_sets? + // this next segment matches students and their grades by dead reckoning + $i =0; foreach($students as $student) { $studentid = $student->id; + debugLog("getting grade for ".($student->id)); $grade = new stdClass(); $grade->userid = $studentid; - $grade->rawgrade = (is_numeric($gradearray[$i])) ? $gradearray[$i] : ''; + $grade->rawgrade = (is_numeric($gradearray[$i])) ? $gradearray[$i] : ''; $grade->feedback = "some text"; $grade->feedbackformat = 0; $grade->usermodified = 0; @@ -235,18 +255,19 @@ function wwassignment_get_user_grades($wwassignment,$userid=0) { // end model - //debugLog("output student grades:" . print_r($studentgrades,true) ); + debugLog("output student grades:" . print_r($studentgrades,true) ); debugLog("End wwassignment_get_user_grades"); return $studentgrades; } /** + * This can be called from outside wwassignment * Update grades by firing grade_updated event * - * @param object $wwassignment object with extra cmidnumber ?? + * @param object $wwassignment object with extra cmidnumber ?? * @param object $wwassignment null means all wwassignments * @param int $userid specific user only, 0 mean all - */ +**/ function wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=true) { debugLog("Begin wwassignment_update_grades"); //debugLog("inputs wwassignment = " . print_r($wwassignment,true)); @@ -265,6 +286,7 @@ function wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=t if ($grades = wwassignment_get_user_grades($wwassignment, $userid)) { # fetches all students if userid=0 foreach($grades as $k=>$v) { + // doctor grades with a negative one if ($v->rawgrade == -1) { $grades[$k]->rawgrade = null; } @@ -274,7 +296,7 @@ function wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=t wwassignment_grade_item_update($wwassignment); } - } else { // find all the assignments + } else { // find all the wwassignments in all courses and update all of them. debugLog("import grades for all wwassignments for all courses"); $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid FROM {wwassignment} a, {course_modules} cm, {modules} m @@ -310,9 +332,20 @@ function wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=t * * @param object $wwassignment object with extra cmidnumber * @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook + * side effect: uses contents of grades to change the values in the gradebook. + * grades contains gradeitem objects containing all of the necessary information + * $grade->userid = $studentid; + * $grade->rawgrade = (is_numeric($gradearray[$i])) ? $gradearray[$i] : ''; + * $grade->feedback = "some text"; + * $grade->feedbackformat = 0; + * $grade->usermodified = 0; + * $grade->dategraded = 0; + * $grade->datesubmitted = 0; + * $grade->id = $studentid; * @return int 0 if ok, error code otherwise - */ +**/ function wwassignment_grade_item_update ($wwassignment, $grades=NULL) { + debugLog("start wwassignment_grade_item_update"); $msg = "Begin wwassignment_grade_item_update"; $msg = ($grades)? $msg . " with grades (updates grade_grades table)" :$msg; debugLog($msg); @@ -332,7 +365,7 @@ function wwassignment_grade_item_update ($wwassignment, $grades=NULL) { $wwsetname = _wwassignment_mapped_set($wwassignment->id,false); $wwassignment->grade = $wwclient->get_max_grade($wwcoursename,$wwsetname,false); } - // set grade in wwassignment + // set maximum grade in wwassignment record as "grade" for the homework set. $params = array('itemname'=>$wwassignment->name, 'idnumber'=>$wwassignment->cmidnumber); @@ -353,10 +386,13 @@ function wwassignment_grade_item_update ($wwassignment, $grades=NULL) { $params['reset'] = true; $grades = NULL; } - # grade_update() defined in gradelib.php - # $grades=NULL means update grade_item table only, otherwise post grades in grade_grades - // error_log("update grades for courseid: ". $wwassignment->courseid . " assignment id: ".$wwassignment->id." time modified ".$wwassignment->timemodified); - return grade_update('mod/wwassignment', $wwassignment->courseid, 'mod', 'wwassignment', $wwassignment->id, 0, $grades, $params); + // grade_update() defined in gradelib.php + // $grades=NULL means update grade_item table only, otherwise post grades in grade_grades + debugLog("wwassignment_grade_item_update: update grades for courseid: ". $wwassignment->courseid . + " assignment id: ".$wwassignment->id." time modified ". + $wwassignment->timemodified."grades".print_r($grades,true)); + return grade_update('mod/wwassignment', $wwassignment->courseid, 'mod', 'wwassignment', + $wwassignment->id, 0, $grades, $params); } /** * Delete grade item for given assignment @@ -578,10 +614,14 @@ function wwassignment_update_dirty_sets() { // update grades for all instances require_once($CFG->dirroot.'/lib/tablelib.php'); $timenow = time(); + ///////////////////////////////////////////////////////////////////// + // Obtain the last time that wwassignment cron processes were triggered. + ///////////////////////////////////////////////////////////////////// $lastcron = $DB->get_field("modules","lastcron",array( "name"=>"wwassignment" )); - $lastcron = 1483202964; # so we get some examples + $lastcron = 1488778000; # so we get some examples + debugLog("1. lastcron is $lastcron and time now is $timenow"); - //////////////////// + $logreader=''; $logmanager = get_log_manager(); $readers = $logmanager->get_readers(); @@ -590,7 +630,7 @@ function wwassignment_update_dirty_sets() { // update grades for all instances } else { $reader = $readers[$logreader]; } - debugLog("reader is not yet known 4"); + if ($reader instanceof \core\log\sql_internal_table_reader) { debugLog("reader is instance of \core\log\sql_internal_table_reader" ); } @@ -601,10 +641,58 @@ function wwassignment_update_dirty_sets() { // update grades for all instances mtrace("don't have access to the right kind of logs"); debugLog("bad logs "); } - debugLog("continue processing"); -// $daystart = (int)$lastcron; // Note: unfortunately pg complains if you use name parameter or column alias in GROUP BY. -// - if ($reader instanceof logstore_legacy\log\store) { + ///////////////////////////////////////////////////////////////////// + // This is the legacy code, it imitates reading from the old log file + ///////////////////////////////////////////////////////////////////// + // $logRecords = get_logs("l.module LIKE \"wwassignment\" AND l.time >$lastcron ", null, "l.time ASC", $counter); + //// The "log" file contains relevent fields + //// time -- of record entry + //// course -- number of course targeted + //// module -- module targeted (e.g. wwassignment) + //// info -- contains the number of wwassignment record (the homework set targeted) + + ////////////////////////////////////////////////////// + //// legacy action: return the record for events targeting wwassignment + //// after the last cron run sorted by time in ascending order + ///////////////////////////////////////////////////// + + // foreach ($logRecords as $record) { + // $wwmodtimes[$wwid =$record->info] = $record->time; + // } + //// legacy action: create a hash $wwmodtimes with key= homework set (wwid), + //// value= last access to that homework set + //// Notice that a given homework set is likely to have been accessed multiple times + //// and this collapses all of those touches into a single reference + + // $idValues= implode(",", array_keys($wwmodtimes) ); + //// legacy action: Create an string with the wwid values ?? wouldn't an array have worked? + + // list($usql,$params) = $DB->get_in_or_equal($idValues); + + ////////////////////////////////////////////////////////////////// + //// legacy action: result is a string $usql (sic) of the form + //// "IN (?,?,?)" and $params an array [23,12,45] + //// where the numbers are wwid's + ////////////////////////////////////////////////////////////////// + + +// $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid, cm.id as wwinstanceid " . +// "FROM {wwassignment} a, {course_modules} cm, {modules} m WHERE m.name = 'wwassignment' " . +// "AND m.id=cm.module AND cm.instance=a.id AND a.id $usql"; +// $rs = $DB->get_recordset_sql($sql,$params)) + + ////////////////////////////////////////////////////////////////// + //// legacy action: select records from wwassignment with id's in $insql (or $usql (sic)) + //// -- and which therefore have been touched since the last cron update + //// join each of these with the record in course_module which references (cm.instance) the record in wwassignmnent + //// and join each these also with the record in modules referenced from course_modules (cm.module). + //// Return the complete wwassignment record, augmented with the course_module idnumber (has inconsistent data) + //// the courseid (a number) and the course_module record id (cm.id) + ////////////////////////////////////////////////////////////////// + + + if ($reader instanceof logstore_legacy\log\store) { + debugLog("Reading from the old style logs"); $logtable = 'log'; $timefield = 'time'; $coursefield = 'course'; @@ -624,6 +712,9 @@ function wwassignment_update_dirty_sets() { // update grades for all instances // $params['courseid'] = $courseid; // } +#################### +# Look for activity involving wwassignment in the general log file +#################### $params['module_type'] = 'course_module'; $params['wwassignment'] = 'wwassignment'; debugLog("using the log table $logtable"); @@ -640,9 +731,22 @@ function wwassignment_update_dirty_sets() { // update grades for all instances // // // // $logRecords = get_logs("l.module LIKE \"wwassignment\" AND l.time >$lastcron ", null, "l.time ASC", $counter,''); + +////////////////////////////////////////////////////////// +// reproducing legacy effect with the call to the "log" table +////////////////////////////////////////////////////////// +// Find all event records which have been created since the last cron update and which +// target a module +// AND the module table is labeled "wwassignment". +// return the time, the courseid, event id, +// the objecttable (named wwassign), and +// the target (module_type) +// !! the objectid (which wwassignment was touched) + $logRecords = $DB->get_records_sql("SELECT $timefield AS time, COUNT(*) AS num, $coursefield AS courseid, target AS target, objecttable AS module, + objectid AS wwassignmentid, id AS eventid FROM {" . $logtable . "} WHERE $timefield > $lastcron @@ -659,10 +763,12 @@ function wwassignment_update_dirty_sets() { // update grades for all instances $wwmodtimes=array(); foreach ($logRecords as $record) { - debugLog("record info ".($record->courseid)); - debugLog("record time ".($record->time)); - $wwmodtimes[$record->courseid] = $record->time; + //debugLog("record courseid ".($record->courseid)); + //debugLog("record wwassignmentid ".($record->wwassignmentid)); + //debugLog("record time ".($record->time)); + $wwmodtimes[$record->wwassignmentid] = $record->time; } + // // // Create an array with the wwid values // $idValues= implode(",", array_keys($wwmodtimes) ); @@ -674,53 +780,80 @@ function wwassignment_update_dirty_sets() { // update grades for all instances // debugLog("values string: $idValues"); // debugLog("last modification times".print_r($wwmodtimes,true)); debugLog("insql ".print_r($insql,true)); - debugLog("array values".print_r(array_values($arraykeys),true)); - debugLog("inparams ".print_r($inparams, true)); - + //debugLog("array values".print_r(array_values($arraykeys),true)); + debugLog("inparams ".print_r($inparams, true)); + + + ///////////////////////////////// ///////////////////////////////// + // Find all of the wwassignment modules that have been touched since the last cron update + ///////////////////////////////// ///////////////////////////////// + // $insql looks like "IN(4,6,78)" where the numbers are ids (a.id) + // of records in the wwassignment table + // these are records of homework sets that have been touched. + // + + ////////////////////////////////////////////////////////////////// + // construct query for wwassignment table + ///////////////////////////////////////////////////////////////// + + // This should be the same query for both the legacy code + // and the new code + $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid, cm.id as wwinstanceid " . "FROM {wwassignment} a, {course_modules} cm, {modules} m - WHERE m.name = 'wwassignment' + WHERE a.id $insql + AND cm.instance=a.id AND m.id=cm.module - AND cm.instance=a.id - AND a.id $insql"; - debugLog("sql is $sql"); -// $sql3 = "SELECT a.* FROM {wwassignment} a WHERE a.id $usql"; -// + AND m.name = 'wwassignment' + "; + debugLog("sql obtained from wwassignment is $sql"); + $rs = $DB->get_recordset_sql($sql,$inparams); + //debugLog("record sets are ".print_r($rs, true)); +//////////////////////////////////////////////////////// +// This seems like a better sql query -- there is a lot of redundancy in the +// original query. Perhaps this just project didn't get finished? +/////////////////////////////////////////////////////// + $sql3 = "SELECT a.* FROM {wwassignment} a WHERE a.id $usql"; + +///////////////////////////////// // -// if ($rs = $DB->get_recordset_sql($sql,$inparams)) { -// debugLog("record sets are ".print_r($rs, true)); -// foreach ( $rs as $wwassignment ) { -// debugLog("one record set ".print_r($wwassignment, true)); -// if (!$wwassignment->cmidnumber) { // is this ever needed? -// $wwassignment->cmidnumber =_wwassignment_cmid() ; -// } -// $wwassignment->timemodified = $wwmodtimes[$wwassignment->id]; -// if ($wwassignment->timemodified > $lastcron) { -// debugLog("instance needs update. timemodified ".$wwassignment->timemodified. -// ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. -// ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); -// if ($wwassignment->grade != 0) { -// debugLog("update entire set ".print_r($wwassignment, true ) ); -// //wwassignment_update_grades($wwassignment); -// } else { -// debugLog("update one item in set ".print_r($wwassignment, true) ); -// //wwassignment_grade_item_update($wwassignment); -// } -// // // refresh events for this assignment -// // _wwassignment_refresh_event($wwassignment); -// // -// } else { -// debugLog("no update needed. timemodified ".$wwassignment->timemodified. -// ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. -// ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); -// } -// -// } -// $rs->close(); -// } + if ($rs = $DB->get_recordset_sql($sql,$inparams)) { + foreach ( $rs as $wwassignment ) { + debugLog("record set ".print_r($wwassignment, true)); + if (!$wwassignment->cmidnumber) { // is this ever needed? + $wwassignment->cmidnumber =_wwassignment_cmid() ; + } + $wwassignment->timemodified = $wwmodtimes[$wwassignment->id]; + if ($wwassignment->timemodified > $lastcron) { + debugLog("instance needs update. timemodified ".$wwassignment->timemodified. + ", lastcron $lastcron, course id ".$wwassignment->course.",\n wwassignment id ".$wwassignment->id. + ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid. + ", grade ".$wwassignment->grade); + if (1) { //FIXME this should check something + wwassignment_update_grades($wwassignment); + debugLog("update entire set ".print_r($wwassignment, true ) ); + + } else { + debugLog("do wwassignment_grade_item_update" ); + wwassignment_grade_item_update($wwassignment); + + } + +// // refresh events for this assignment +// _wwassignment_refresh_event($wwassignment); +// + } else { // ?? shouldn't every record with id in $usql need an update? why the extra check. + debugLog("no update needed. timemodified ".$wwassignment->timemodified. + ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. + ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); + } + + } + $rs->close(); + } debugLog("done with updating dirty sets"); return(true); } diff --git a/locallib.php b/locallib.php index c14f018..18a3fb0 100644 --- a/locallib.php +++ b/locallib.php @@ -53,15 +53,17 @@ function _wwassignment_get_course_students($courseid) { //debugLog("roles used ". print_r($roles_used_in_context, true)); foreach($roles_used_in_context as $role) { $roleid = $role->id; - debugLog( "roleid should be 5 for a student $roleid"); + //debugLog( "roleid should be 5 for a student $roleid"); //debugLog(get_role_users($roleid, $context, true) ); if ($new_users = get_role_users($roleid, $context, true) ) { $users = array_merge($users, $new_users );//FIXME a user could be liseted twice } - debugLog("display users ".print_r($users,true)); + //debugLog("display users ".print_r($users,true)); } debugLog("display users in course--on"); - debugLog("users again".print_r($users, true)); + foreach($users as $item) { + debugLog("user: ".$item->lastname); + } debugLog("End get_course_students($courseid )"); return $users; @@ -242,8 +244,8 @@ function _wwassignment_login_user($wwcoursename,$wwusername) { */ function _wwassignment_cmid() { global $DB; - $wwassignment = $DB->get_record('modules', array( 'name'=>'wwassignment' )); - return $wwassignment->id; + $wwassignment_module = $DB->get_record('modules', array( 'name'=>'wwassignment' )); + return $wwassignment_module->id; } /** From 9235e8c4b30026c2578916f669e71e1ba0a4b69c Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Mon, 6 Mar 2017 09:08:10 -0500 Subject: [PATCH 03/10] Set another piton in the effort to debug the cron update. --- lib.php | 40 ++++++++++++++++------------------------ locallib.php | 13 +++++++------ 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/lib.php b/lib.php index abedb28..1859f37 100644 --- a/lib.php +++ b/lib.php @@ -32,11 +32,9 @@ // wwassignment_update_grade_item(wwassignment) -- just updates grade_item table // wwassignment_update_grade_item(wwassignment, grades) updates grade_item table and grade_grades table //////////////////////////////////////////////////////////////// - - function grade_update($source, $courseid, $itemtype, $itemmodule, - $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL) { - error_log("function grade_update called but not implemented") - } + +// not sure why this function is still here. +// function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL) { /** * Refetches data from all course activities @@ -195,8 +193,8 @@ function wwassignment_delete_instance($wwassignmentid) { function wwassignment_get_user_grades($wwassignment,$userid=0) { - debugLog("Begin wwassignment_get_user_grades"); - //debugLog("inputs -- wwassignment" . print_r($wwassignment,true)); + debugLog("Begin wwassignment_get_user_grades -- fetching grades from webwork"); + debugLog("inputs -- wwassignment" . print_r($wwassignment,true)); debugLog("userid = $userid"); require_once("locallib.php"); @@ -221,11 +219,8 @@ function wwassignment_get_user_grades($wwassignment,$userid=0) { } } // get data from WeBWorK - debugLog("calling 'grade_users_sets'"); - debugLog("course $wwcoursename set $wwsetname"); - debugLog("students ".print_r($usernamearray,true)); - $gradearray = $wwclient->grade_users_sets($wwcoursename, - $usernamearray,$wwsetname); + debugLog("fetch grades from course: $wwcoursename set: $wwsetname"); + $gradearray = $wwclient->grade_users_sets($wwcoursename,$usernamearray,$wwsetname); // returns an array of grades -- the number of questions answered correctly? // debugLog("usernamearray " . print_r($usernamearray, true)); @@ -238,7 +233,6 @@ function wwassignment_get_user_grades($wwassignment,$userid=0) { $i =0; foreach($students as $student) { $studentid = $student->id; - debugLog("getting grade for ".($student->id)); $grade = new stdClass(); $grade->userid = $studentid; $grade->rawgrade = (is_numeric($gradearray[$i])) ? $gradearray[$i] : ''; @@ -620,7 +614,7 @@ function wwassignment_update_dirty_sets() { // update grades for all instances $lastcron = $DB->get_field("modules","lastcron",array( "name"=>"wwassignment" )); $lastcron = 1488778000; # so we get some examples - debugLog("1. lastcron is $lastcron and time now is $timenow"); + debugLog("wwassignment_update_dirty_sets: lastcron is $lastcron and time now is $timenow"); $logreader=''; $logmanager = get_log_manager(); @@ -632,14 +626,14 @@ function wwassignment_update_dirty_sets() { // update grades for all instances } if ($reader instanceof \core\log\sql_internal_table_reader) { - debugLog("reader is instance of \core\log\sql_internal_table_reader" ); + debugLog("wwassignment_update_dirty_sets: reader is instance of \core\log\sql_internal_table_reader" ); } // If reader is not a sql_internal_table_reader and not legacy store then return. if (!($reader instanceof \core\log\sql_internal_table_reader) && !($reader instanceof logstore_legacy\log\store)) { //return array(); - mtrace("don't have access to the right kind of logs"); - debugLog("bad logs "); + mtrace("wwassignment_update_dirty_sets:don't have access to the right kind of logs"); + debugLog("wwassignment_update_dirty_sets:bad logs "); } ///////////////////////////////////////////////////////////////////// // This is the legacy code, it imitates reading from the old log file @@ -692,7 +686,7 @@ function wwassignment_update_dirty_sets() { // update grades for all instances if ($reader instanceof logstore_legacy\log\store) { - debugLog("Reading from the old style logs"); + debugLog("wwassignment_update_dirty_sets:Reading from the old style logs"); $logtable = 'log'; $timefield = 'time'; $coursefield = 'course'; @@ -754,11 +748,9 @@ function wwassignment_update_dirty_sets() { // update grades for all instances AND objecttable = :wwassignment GROUP BY $timefield", $params); $number_of_log_records = count($logRecords); - debugLog("number of logRecords $number_of_log_records"); + debugLog("wwassignment_update_dirty_sets:number of logRecords $number_of_log_records"); //debugLog(print_r($logRecords,true)); - - mtrace("2. last CRON is $lastcron, then TIMENOW $timenow"); - + $wwmodtimes=array(); @@ -779,7 +771,7 @@ function wwassignment_update_dirty_sets() { // update grades for all instances // //list($insql, $inparams) = $DB->get_in_or_equal($wwmodtimes,SQL_PARAMS_NAMED); // debugLog("values string: $idValues"); // debugLog("last modification times".print_r($wwmodtimes,true)); - debugLog("insql ".print_r($insql,true)); + //debugLog("insql ".print_r($insql,true)); //debugLog("array values".print_r(array_values($arraykeys),true)); debugLog("inparams ".print_r($inparams, true)); @@ -816,7 +808,7 @@ function wwassignment_update_dirty_sets() { // update grades for all instances // This seems like a better sql query -- there is a lot of redundancy in the // original query. Perhaps this just project didn't get finished? /////////////////////////////////////////////////////// - $sql3 = "SELECT a.* FROM {wwassignment} a WHERE a.id $usql"; + //$sql3 = "SELECT a.* FROM {wwassignment} a WHERE a.id $usql"; ///////////////////////////////// // diff --git a/locallib.php b/locallib.php index 18a3fb0..eff0d45 100644 --- a/locallib.php +++ b/locallib.php @@ -43,24 +43,25 @@ function debugLog($message) { */ function _wwassignment_get_course_students($courseid) { - debugLog("Begin get_course_students($courseid )"); + debugLog("Begin get_course_students($courseid ) which fetches all the students in the course"); debugLog("courseID is ". print_r($courseid, true)); $context = context_course::instance($courseid); debugLog("context is ". print_r($context, true)); $users = array(); $roles_used_in_context = get_roles_used_in_context($context); - //debugLog("roles used ". print_r($roles_used_in_context, true)); + debugLog("roles used ". print_r($roles_used_in_context, true)); foreach($roles_used_in_context as $role) { $roleid = $role->id; - //debugLog( "roleid should be 5 for a student $roleid"); - //debugLog(get_role_users($roleid, $context, true) ); + debugLog( "roleid should be 5 for a student $roleid"); + debugLog(get_role_users($roleid, $context, true) ); if ($new_users = get_role_users($roleid, $context, true) ) { - $users = array_merge($users, $new_users );//FIXME a user could be liseted twice + $users = array_merge($users, $new_users ); + //FIXME a user could be listed twice if they had two roles. } //debugLog("display users ".print_r($users,true)); } - debugLog("display users in course--on"); + debugLog("getting logins of users in courseid $courseid"); foreach($users as $item) { debugLog("user: ".$item->lastname); } From a2349861d541cd0d086421f9b82a81337f93246a Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sat, 11 Mar 2017 09:37:24 -0500 Subject: [PATCH 04/10] Another piton. Still not working right, but it does compile and there are many messages for tracking progress. --- lib.php | 6 +++--- locallib.php | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib.php b/lib.php index 1859f37..1d294c6 100644 --- a/lib.php +++ b/lib.php @@ -520,6 +520,7 @@ function wwassignment_print_recent_activity($course, $isteacher, $timestart) { * returns true if successful */ function wwassignment_cron() { + mtrace("-----------------------begin wwassignment_cron-----------------------"); debugLog("Begin wwassignment_cron"); //FIXME: Add a call that updates all events with dates (in case people forgot to push) @@ -528,9 +529,8 @@ function wwassignment_cron() { //wwassignment_update_grades(null,0); //try { // try didn't work on some php systems -- leave it out. wwassignment_update_dirty_sets(); - mtrace("wwassignment cron"); debugLog("End wwassignment_cron"); - mtrace("wwassignment cron"); + mtrace("-----------------------end wwassignment_cron-----------------------"); return true; } @@ -835,7 +835,7 @@ function wwassignment_update_dirty_sets() { // update grades for all instances } // // refresh events for this assignment -// _wwassignment_refresh_event($wwassignment); + _wwassignment_refresh_event($wwassignment); // } else { // ?? shouldn't every record with id in $usql need an update? why the extra check. debugLog("no update needed. timemodified ".$wwassignment->timemodified. diff --git a/locallib.php b/locallib.php index eff0d45..9734553 100644 --- a/locallib.php +++ b/locallib.php @@ -411,18 +411,19 @@ function handler($functioncall,$params=array(),$override=false) { $params = array_merge($this->defaultparams,$params); } if(WWASSIGNMENT_DEBUG) { - echo "Called: $functioncall
"; + echo "Handler called: $functioncall
"; echo "Params: "; var_dump($params); echo "
"; } $result = $this->client->__soapCall($functioncall,$params); - - //$result = call_user_func_array(array(&$this->client,$functioncall),$params); -# if($err = $this->client->getError()) { -# //print_error(get_string("rpc_fault","wwassignment') . " " . $functioncall. " ". $err); -# print_error('rpc_error','wwassignment'); -# } + debugLog("result is ".print_r($result, true)); + // FIXME what does call_user_func array do?); +// $result = call_user_func_array(array(&$this->client,$functioncall),$params); +// if($err = $this->client->getError()) { +// //print_error(get_string("rpc_fault","wwassignment') . " " . $functioncall. " ". $err); +// print_error('rpc_error','wwassignment'); +// } return $result; } From 1fc7bdb72c362fb2c36a194a54fae13893c1190d Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sat, 11 Mar 2017 20:29:29 -0500 Subject: [PATCH 05/10] Made modifications, mainly to comments and traceLog and debugLog entries --- lib.php | 448 ++++++++++++--------------------------------------- locallib.php | 362 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 423 insertions(+), 387 deletions(-) diff --git a/lib.php b/lib.php index 1d294c6..7809796 100644 --- a/lib.php +++ b/lib.php @@ -61,8 +61,7 @@ function wwassignment_install() { */ function wwassignment_add_instance($wwassignment) { global $COURSE,$DB; - - debugLog("Begin wwassignment_add_instance"); + traceLog("-----------Begin wwassignment_add_instance-----------"); debugLog("input wwassignment "); //debugLog( print_r($wwassignment, true) ); @@ -87,7 +86,7 @@ function wwassignment_add_instance($wwassignment) { //notify gradebook wwassignment_grade_item_update($wwassignment); } - debugLog("End wwassignment_add_instance"); + traceLog("----------End wwassignment_add_instance------------"); return $returnid; } @@ -100,7 +99,7 @@ function wwassignment_add_instance($wwassignment) { function wwassignment_update_instance($wwassignment) { global $COURSE,$DB; require_once("locallib.php"); - debugLog("Begin wwassignment_update_instance"); + traceLog("---------Begin wwassignment_update_instance---------"); //checking mappings @@ -124,7 +123,7 @@ function wwassignment_update_instance($wwassignment) { //notify gradebook -- update grades for this wwassignment only wwassignment_grade_item_update($wwassignment); wwassignment_update_grades($wwassignment); - debugLog("End wwassignment_update_instance"); + traceLog("-------End wwassignment_update_instance---------"); return $returnid; } @@ -134,12 +133,10 @@ function wwassignment_update_instance($wwassignment) { * @param integer $wwassignmentid The id of the assignment to delete. * @return bool Delete was successful or not. */ -function wwassignment_delete_instance($wwassignmentid) { - +function wwassignment_delete_instance($wwassignmentid) { global $DB; - - debugLog("Begin wwassignment_delete_instance -- input wwassignmentid:"); - debugLog(print_r($wwassignmentid,true)); + traceLog("---------- Begin wwassignment_delete_instance -------------"); + debugLog("input wwassignmentid:".print_r($wwassignmentid,true)); $result = true; #delete DB record @@ -169,8 +166,7 @@ function wwassignment_delete_instance($wwassignmentid) { //notify gradebook wwassignment_grade_item_delete($wwassignment); - debugLog("End wwassignment_delete_instance -- input wwassignmentid:"); - + traceLog("------- End wwassignment_delete_instance --------"); return $result; } @@ -193,7 +189,7 @@ function wwassignment_delete_instance($wwassignmentid) { function wwassignment_get_user_grades($wwassignment,$userid=0) { - debugLog("Begin wwassignment_get_user_grades -- fetching grades from webwork"); + traceLog("------Begin wwassignment_get_user_grades -- fetch grades from WW -----"); debugLog("inputs -- wwassignment" . print_r($wwassignment,true)); debugLog("userid = $userid"); @@ -250,7 +246,7 @@ function wwassignment_get_user_grades($wwassignment,$userid=0) { // end model debugLog("output student grades:" . print_r($studentgrades,true) ); - debugLog("End wwassignment_get_user_grades"); + traceLog("---------End wwassignment_get_user_grades---------"); return $studentgrades; } @@ -263,7 +259,7 @@ function wwassignment_get_user_grades($wwassignment,$userid=0) { * @param int $userid specific user only, 0 mean all **/ function wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=true) { - debugLog("Begin wwassignment_update_grades"); + traceLog("------- Begin wwassignment_update_grades---------"); //debugLog("inputs wwassignment = " . print_r($wwassignment,true)); debugLog("userid = $userid"); global $CFG, $DB; @@ -318,7 +314,7 @@ function wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=t } } - debugLog("End wwassignment_update_grades"); + traceLog("--------End wwassignment_update_grades--------"); } /** @@ -339,7 +335,7 @@ function wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=t * @return int 0 if ok, error code otherwise **/ function wwassignment_grade_item_update ($wwassignment, $grades=NULL) { - debugLog("start wwassignment_grade_item_update"); + traceLog("------- Begin wwassignment_grade_item_update ------- "); $msg = "Begin wwassignment_grade_item_update"; $msg = ($grades)? $msg . " with grades (updates grade_grades table)" :$msg; debugLog($msg); @@ -385,6 +381,7 @@ function wwassignment_grade_item_update ($wwassignment, $grades=NULL) { debugLog("wwassignment_grade_item_update: update grades for courseid: ". $wwassignment->courseid . " assignment id: ".$wwassignment->id." time modified ". $wwassignment->timemodified."grades".print_r($grades,true)); + traceLog("------- end wwassignment_grade_item_update ------- "); return grade_update('mod/wwassignment', $wwassignment->courseid, 'mod', 'wwassignment', $wwassignment->id, 0, $grades, $params); } @@ -395,7 +392,7 @@ function wwassignment_grade_item_update ($wwassignment, $grades=NULL) { * @return object wwassignment ???? */ function wwassignment_grade_item_delete($wwassignment) { - debugLog("Begin wwassignment_grade_item_delete"); + traceLog("-------Begin wwassignment_grade_item_delete------"); debugLog("inputs wwassignment " . print_r($wwassignment, true) ); global $CFG; @@ -404,7 +401,7 @@ function wwassignment_grade_item_delete($wwassignment) { if (!isset($wwassignment->courseid)) { $wwassignment->courseid = $wwassignment->course; } - debugLog("End wwassignment_grade_item_delete"); + traceLog("-------End wwassignment_grade_item_delete---------"); return grade_update('mod/wwassignment', $wwassignment->courseid, 'mod', 'wwassignment', $wwassignment->id, 0, NULL, array('deleted'=>1)); @@ -415,9 +412,9 @@ function wwassignment_grade_item_delete($wwassignment) { * This is done by calling the update_instance() method of the assignment type class */ function wwassignment_item_update($wwassignment) { - debugLog("Begin wwassignment_item_update -- not yet defined!!!!"); + traceLog("------Begin wwassignment_item_update -- not yet defined!!!!------"); debugLog("input wwassignment " . print_r($wwassignment,true) ); - debugLog("End wwassignment_item_update -- not yet defined!!!!"); + traceLog("-------End wwassignment_item_update -- not yet defined!!!!-------"); } /** * @desc Contacts webwork to find out the completion status of a problem set for all users in a course. @@ -425,7 +422,7 @@ function wwassignment_item_update($wwassignment) { * @return object The student grades indexed by student ID. */ function wwassignment_grades($wwassignmentid) { -// error_log("Begin wwassignment_grades -- legacy function?"); + traceLog("------ Begin wwassignment_grades -- legacy function?-------"); global $COURSE,$DB; $wwclient = new wwassignment_client(); $wwassignment = $DB->get_record('wwassignment', array( 'id'=>$wwassignmentid )); @@ -455,6 +452,7 @@ function wwassignment_grades($wwassignmentid) { } $studentgrades->maxgrade = $wwclient->get_max_grade($wwcoursename,$wwsetname); // error_log("End wwassignment_grades -- legacy function?"); + traceLog("------ End wwassignment_grades -- legacy function?-------"); return $studentgrades; } @@ -467,11 +465,13 @@ function wwassignment_grades($wwassignmentid) { * @return array Representing time, info pairing. */ function wwassignment_user_outline($course, $user, $mod, $wwassignment) { + traceLog("--------Begin wwassignment_user_outline-----------------"); $aLogs = get_logs("l.userid=$user AND l.course=$course AND l.cmid={$wwassignment->id}"); if( count($aLogs) > 0 ) { $return->time = $aLogs[0]->time; $return->info = $aLogs[0]->info; } + traceLog("--------End wwassignment_user_outline-----------------"); return $return; } @@ -509,7 +509,8 @@ function wwassignment_delete_userdata() { */ function wwassignment_print_recent_activity($course, $isteacher, $timestart) { global $CFG; -// error_log("Begin wwassignment_print_recent_activity --not used yet"); + traceLog("-------- Begin wwassignment_print_recent_activity --not used yet -------"); + traceLog("-------- End wwassignment_print_recent_activity --not used yet -------"); return false; // True if anything was printed, otherwise false } @@ -520,17 +521,15 @@ function wwassignment_print_recent_activity($course, $isteacher, $timestart) { * returns true if successful */ function wwassignment_cron() { - mtrace("-----------------------begin wwassignment_cron-----------------------"); - debugLog("Begin wwassignment_cron"); + traceLog("-------------Begin wwassignment_cron-------------------------"); //FIXME: Add a call that updates all events with dates (in case people forgot to push) //wwassignment_refresh_events(); //FIXME: Add a call that updates all grades in all courses //wwassignment_update_grades(null,0); //try { // try didn't work on some php systems -- leave it out. - wwassignment_update_dirty_sets(); - debugLog("End wwassignment_cron"); - mtrace("-----------------------end wwassignment_cron-----------------------"); + _wwassignment_update_dirty_sets(); + traceLog("---------------------End wwassignment_cron------------------------"); return true; } @@ -599,257 +598,6 @@ function wwassignment_cron() { // timecreated // courseid -function wwassignment_update_dirty_sets() { // update grades for all instances which have been modified since last cronjob - global $CFG,$DB; - global $CFG; -require_once($CFG->dirroot.'/course/lib.php'); -require_once($CFG->dirroot.'/report/log/locallib.php'); -require_once($CFG->libdir.'/adminlib.php'); -require_once($CFG->dirroot.'/lib/tablelib.php'); - - $timenow = time(); - ///////////////////////////////////////////////////////////////////// - // Obtain the last time that wwassignment cron processes were triggered. - ///////////////////////////////////////////////////////////////////// - $lastcron = $DB->get_field("modules","lastcron",array( "name"=>"wwassignment" )); - $lastcron = 1488778000; # so we get some examples - - debugLog("wwassignment_update_dirty_sets: lastcron is $lastcron and time now is $timenow"); - - $logreader=''; - $logmanager = get_log_manager(); - $readers = $logmanager->get_readers(); - if (empty($logreader)) { - $reader = reset($readers); - } else { - $reader = $readers[$logreader]; - } - - if ($reader instanceof \core\log\sql_internal_table_reader) { - debugLog("wwassignment_update_dirty_sets: reader is instance of \core\log\sql_internal_table_reader" ); - } - - // If reader is not a sql_internal_table_reader and not legacy store then return. - if (!($reader instanceof \core\log\sql_internal_table_reader) && !($reader instanceof logstore_legacy\log\store)) { - //return array(); - mtrace("wwassignment_update_dirty_sets:don't have access to the right kind of logs"); - debugLog("wwassignment_update_dirty_sets:bad logs "); - } - ///////////////////////////////////////////////////////////////////// - // This is the legacy code, it imitates reading from the old log file - ///////////////////////////////////////////////////////////////////// - // $logRecords = get_logs("l.module LIKE \"wwassignment\" AND l.time >$lastcron ", null, "l.time ASC", $counter); - //// The "log" file contains relevent fields - //// time -- of record entry - //// course -- number of course targeted - //// module -- module targeted (e.g. wwassignment) - //// info -- contains the number of wwassignment record (the homework set targeted) - - ////////////////////////////////////////////////////// - //// legacy action: return the record for events targeting wwassignment - //// after the last cron run sorted by time in ascending order - ///////////////////////////////////////////////////// - - // foreach ($logRecords as $record) { - // $wwmodtimes[$wwid =$record->info] = $record->time; - // } - //// legacy action: create a hash $wwmodtimes with key= homework set (wwid), - //// value= last access to that homework set - //// Notice that a given homework set is likely to have been accessed multiple times - //// and this collapses all of those touches into a single reference - - // $idValues= implode(",", array_keys($wwmodtimes) ); - //// legacy action: Create an string with the wwid values ?? wouldn't an array have worked? - - // list($usql,$params) = $DB->get_in_or_equal($idValues); - - ////////////////////////////////////////////////////////////////// - //// legacy action: result is a string $usql (sic) of the form - //// "IN (?,?,?)" and $params an array [23,12,45] - //// where the numbers are wwid's - ////////////////////////////////////////////////////////////////// - - -// $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid, cm.id as wwinstanceid " . -// "FROM {wwassignment} a, {course_modules} cm, {modules} m WHERE m.name = 'wwassignment' " . -// "AND m.id=cm.module AND cm.instance=a.id AND a.id $usql"; -// $rs = $DB->get_recordset_sql($sql,$params)) - - ////////////////////////////////////////////////////////////////// - //// legacy action: select records from wwassignment with id's in $insql (or $usql (sic)) - //// -- and which therefore have been touched since the last cron update - //// join each of these with the record in course_module which references (cm.instance) the record in wwassignmnent - //// and join each these also with the record in modules referenced from course_modules (cm.module). - //// Return the complete wwassignment record, augmented with the course_module idnumber (has inconsistent data) - //// the courseid (a number) and the course_module record id (cm.id) - ////////////////////////////////////////////////////////////////// - - - if ($reader instanceof logstore_legacy\log\store) { - debugLog("wwassignment_update_dirty_sets:Reading from the old style logs"); - $logtable = 'log'; - $timefield = 'time'; - $coursefield = 'course'; - // Anonymous actions are never logged in legacy log. - $nonanonymous = ''; - } else { - $logtable = $reader->get_internal_log_table_name(); - $timefield = 'timecreated'; - $coursefield = 'courseid'; - $nonanonymous = 'AND anonymous = 0'; - } - -// -// $courseselect = ''; -// if ($courseid) { -// $courseselect = "AND $coursefield = :courseid"; -// $params['courseid'] = $courseid; -// } - -#################### -# Look for activity involving wwassignment in the general log file -#################### - $params['module_type'] = 'course_module'; - $params['wwassignment'] = 'wwassignment'; - debugLog("using the log table $logtable"); -// -// //$daystart = (int)$daystart; // Note: unfortunately pg complains if you use name parameter or column alias in GROUP BY. -// //////////////// -// //error_log ("sql string = $sql"); -// // Could we speed this up by getting all of the log records pertaining to webwork in one go? -// // Or perhaps just the log records which have occured after the lastcron date -// // Then create a hash with wwassignment->id => timemodified -// // means just one database lookup -// $counter = 0; -// // this is most likely what needs to be replaced -// -// -// // $logRecords = get_logs("l.module LIKE \"wwassignment\" AND l.time >$lastcron ", null, "l.time ASC", $counter,''); - -////////////////////////////////////////////////////////// -// reproducing legacy effect with the call to the "log" table -////////////////////////////////////////////////////////// -// Find all event records which have been created since the last cron update and which -// target a module -// AND the module table is labeled "wwassignment". -// return the time, the courseid, event id, -// the objecttable (named wwassign), and -// the target (module_type) -// !! the objectid (which wwassignment was touched) - - $logRecords = $DB->get_records_sql("SELECT $timefield AS time, COUNT(*) AS num, - $coursefield AS courseid, target AS target, - objecttable AS module, - objectid AS wwassignmentid, - id AS eventid - FROM {" . $logtable . "} - WHERE $timefield > $lastcron - AND target = :module_type - AND objecttable = :wwassignment - GROUP BY $timefield", $params); - $number_of_log_records = count($logRecords); - debugLog("wwassignment_update_dirty_sets:number of logRecords $number_of_log_records"); - //debugLog(print_r($logRecords,true)); - - - - $wwmodtimes=array(); - foreach ($logRecords as $record) { - //debugLog("record courseid ".($record->courseid)); - //debugLog("record wwassignmentid ".($record->wwassignmentid)); - //debugLog("record time ".($record->time)); - $wwmodtimes[$record->wwassignmentid] = $record->time; - } - -// -// // Create an array with the wwid values -// $idValues= implode(",", array_keys($wwmodtimes) ); -// //list($insql,$inparams) = $DB->get_in_or_equal($idValues,SQL_PARAMS_NAMED); - $arraykeys = array_keys($wwmodtimes); -// //debugLog("array_keys ".print_r($arraykeys,true)); - list($insql,$inparams) = $DB->get_in_or_equal($arraykeys,SQL_PARAMS_NAMED); -// //list($insql, $inparams) = $DB->get_in_or_equal($wwmodtimes,SQL_PARAMS_NAMED); -// debugLog("values string: $idValues"); -// debugLog("last modification times".print_r($wwmodtimes,true)); - //debugLog("insql ".print_r($insql,true)); - //debugLog("array values".print_r(array_values($arraykeys),true)); - debugLog("inparams ".print_r($inparams, true)); - - - ///////////////////////////////// ///////////////////////////////// - // Find all of the wwassignment modules that have been touched since the last cron update - ///////////////////////////////// ///////////////////////////////// - // $insql looks like "IN(4,6,78)" where the numbers are ids (a.id) - // of records in the wwassignment table - // these are records of homework sets that have been touched. - // - - ////////////////////////////////////////////////////////////////// - // construct query for wwassignment table - ///////////////////////////////////////////////////////////////// - - // This should be the same query for both the legacy code - // and the new code - - $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid, - cm.id as wwinstanceid " . - "FROM {wwassignment} a, - {course_modules} cm, - {modules} m - WHERE a.id $insql - AND cm.instance=a.id - AND m.id=cm.module - AND m.name = 'wwassignment' - "; - debugLog("sql obtained from wwassignment is $sql"); - $rs = $DB->get_recordset_sql($sql,$inparams); - //debugLog("record sets are ".print_r($rs, true)); -//////////////////////////////////////////////////////// -// This seems like a better sql query -- there is a lot of redundancy in the -// original query. Perhaps this just project didn't get finished? -/////////////////////////////////////////////////////// - //$sql3 = "SELECT a.* FROM {wwassignment} a WHERE a.id $usql"; - -///////////////////////////////// -// - if ($rs = $DB->get_recordset_sql($sql,$inparams)) { - foreach ( $rs as $wwassignment ) { - debugLog("record set ".print_r($wwassignment, true)); - if (!$wwassignment->cmidnumber) { // is this ever needed? - $wwassignment->cmidnumber =_wwassignment_cmid() ; - } - $wwassignment->timemodified = $wwmodtimes[$wwassignment->id]; - if ($wwassignment->timemodified > $lastcron) { - debugLog("instance needs update. timemodified ".$wwassignment->timemodified. - ", lastcron $lastcron, course id ".$wwassignment->course.",\n wwassignment id ".$wwassignment->id. - ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid. - ", grade ".$wwassignment->grade); - if (1) { //FIXME this should check something - wwassignment_update_grades($wwassignment); - debugLog("update entire set ".print_r($wwassignment, true ) ); - - } else { - debugLog("do wwassignment_grade_item_update" ); - wwassignment_grade_item_update($wwassignment); - - } - -// // refresh events for this assignment - _wwassignment_refresh_event($wwassignment); -// - } else { // ?? shouldn't every record with id in $usql need an update? why the extra check. - debugLog("no update needed. timemodified ".$wwassignment->timemodified. - ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. - ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); - } - - } - $rs->close(); - } - debugLog("done with updating dirty sets"); - return(true); -} - /** * @desc Finds all the participants in the course @@ -866,77 +614,83 @@ function wwassignment_get_participants($wwassignmentid) { return _wwassignment_get_course_students( $wwassignment->course ); } - +//FIXME -- this should be restored function wwassignment_refresh_events($courseid = 0) { -// error_log('wwassignment_refresh_events called --not yet defined'); - global $DB; -// This standard function will check all instances of this module -// and make sure there are up-to-date events created for each of them. -// If courseid = 0, then every wwassignment event in the site is checked, else -// only wwassignment events belonging to the course specified are checked. -// This function is used, in its new format, by restore_refresh_events() and by the cron function -// - // find wwassignment instances associated with this course or all wwassignment modules - $courses = array(); # create array of courses - if ($courseid) { - if (! $wwassignments = $DB->get_records("wwassignment", array("course"=>$courseid) )) { - return true; - } else { - $courses[$courseid]= array(); // collect wwassignments for this course - array_push( $courses[$courseid], $wwassignments ); - } - } else { - if (! $wwassignments = $DB->get_records("wwassignment")) { - return true; - } else { - foreach ($wwassignments as $ww ) { - // collect wwassignments for each course -// error_log("course id ".$ww->course); - if (! ($courses[$ww->course] ) ) { - $courses[$ww->course] = array(); - } - array_push($courses[$ww->course], $ww) ; // push wwassignment onto an exisiting one - } - } - - } - - - // $courses now holds a list of courses with wwassignment modules - $moduleid = _wwassignment_cmid(); - $cids = array_keys($courses); # collect course ids -// error_log("cids".print_r($cids, true)); - $wwclient = new wwassignment_client(); - foreach ($cids as $cid) { - // connect to WeBWorK - $wwcoursename = _wwassignment_mapped_course($cid,false); - $wwassignment->webwork_course = $wwcoursename; - if ( $wwcoursename== -1) { -// error_log("Can't connect course $cid to webwork"); - break; - } - // retrieve wwassignments associated with this course - foreach($courses[$cid] as $wwassignment ) { - //checking mappings - $wwsetname = $wwassignment->webwork_set; -// error_log("updating events for $wwcoursename $wwsetname"); - //get data from WeBWorK - $wwsetdata = $wwclient->get_assignment_data($wwcoursename,$wwsetname,false); - $wwassignment->grade = $wwclient->get_max_grade($wwcoursename,$wwsetname,false); - $wwassignment->timemodified = time(); - $returnid = $DB->update_record('wwassignment',$wwassignment); - // update event - //this part won't work because these items implicitly require the course. - _wwassignment_delete_events($wwassignment->id); - _wwassignment_create_events($wwassignment, $wwsetdata); - } - - } - - - return true; + global $DB; + traceLog("----------------- Begin wwassignment_refresh_events ---------------"); + _wwassignment_refresh_events($courseid); + traceLog("----------------- End wwassignment_refresh_events ---------------"); } + +// +// // This standard function will check all instances of this module +// // and make sure there are up-to-date events created for each of them. +// // If courseid = 0, then every wwassignment event in the site is checked, else +// // only wwassignment events belonging to the course specified are checked. +// // This function is used, in its new format, by restore_refresh_events() and by the cron function +// // +// // find wwassignment instances associated with this course or all wwassignment modules +// $courses = array(); # create array of courses +// if ($courseid) { +// if (! $wwassignments = $DB->get_records("wwassignment", array("course"=>$courseid) )) { +// return true; +// } else { +// $courses[$courseid]= array(); // collect wwassignments for this course +// array_push( $courses[$courseid], $wwassignments ); +// } +// } else { +// if (! $wwassignments = $DB->get_records("wwassignment")) { +// return true; +// } else { +// foreach ($wwassignments as $ww ) { +// // collect wwassignments for each course +// // error_log("course id ".$ww->course); +// if (! ($courses[$ww->course] ) ) { +// $courses[$ww->course] = array(); +// } +// array_push($courses[$ww->course], $ww) ; // push wwassignment onto an exisiting one +// } +// } +// +// } +// +// +// // $courses now holds a list of courses with wwassignment modules +// $moduleid = _wwassignment_cmid(); +// $cids = array_keys($courses); # collect course ids +// // error_log("cids".print_r($cids, true)); +// $wwclient = new wwassignment_client(); +// foreach ($cids as $cid) { +// // connect to WeBWorK +// $wwcoursename = _wwassignment_mapped_course($cid,false); +// $wwassignment->webwork_course = $wwcoursename; +// if ( $wwcoursename== -1) { +// // error_log("Can't connect course $cid to webwork"); +// break; +// } +// // retrieve wwassignments associated with this course +// foreach($courses[$cid] as $wwassignment ) { +// //checking mappings +// $wwsetname = $wwassignment->webwork_set; +// // error_log("updating events for $wwcoursename $wwsetname"); +// //get data from WeBWorK +// $wwsetdata = $wwclient->get_assignment_data($wwcoursename,$wwsetname,false); +// $wwassignment->grade = $wwclient->get_max_grade($wwcoursename,$wwsetname,false); +// $wwassignment->timemodified = time(); +// $returnid = $DB->update_record('wwassignment',$wwassignment); +// // update event +// //this part won't work because these items implicitly require the course. +// _wwassignment_delete_events($wwassignment->id); +// _wwassignment_create_events($wwassignment, $wwsetdata); +// } +// +// } +// traceLog("----------------- End wwassignment_refresh_events ---------------"); +// +// return true; +// } + // High level grade calls ins gradelib.php diff --git a/locallib.php b/locallib.php index 9734553..6ed0183 100644 --- a/locallib.php +++ b/locallib.php @@ -3,8 +3,10 @@ #require_once("$CFG->libdir/soap/nusoap.php"); require_once("$CFG->libdir/soaplib.php"); -//define('WWASSIGNMENT_DEBUG',0); - define('WWASSIGNMENT_DEBUG',1); +define('WWASSIGNMENT_DEBUG',0); +// define('WWASSIGNMENT_DEBUG',1); +//define('WWASSIGNMENT_TRACE',0); + define('WWASSIGNMENT_TRACE',1); ////////////////////////////////////////////////////////////////// @@ -23,6 +25,12 @@ function debugLog($message) { } } +function traceLog($message) { + if (WWASSIGNMENT_TRACE) { + error_log($message); + mtrace($message); + } +} /** (reference from accesslib.php ) * @desc gets all the users assigned this role in this context or higher * @param int roleid (can also be an array of ints!) @@ -43,7 +51,8 @@ function debugLog($message) { */ function _wwassignment_get_course_students($courseid) { - debugLog("Begin get_course_students($courseid ) which fetches all the students in the course"); + traceLog("---------------Begin get_course_students($courseid )------------ "); + traceLog("which fetches all the students in the course"); debugLog("courseID is ". print_r($courseid, true)); $context = context_course::instance($courseid); debugLog("context is ". print_r($context, true)); @@ -66,7 +75,7 @@ function _wwassignment_get_course_students($courseid) { debugLog("user: ".$item->lastname); } - debugLog("End get_course_students($courseid )"); + traceLog("---------------End get_course_students($courseid )------------ "); return $users; @@ -86,54 +95,78 @@ function _wwassignment_get_course_students($courseid) { */ function _wwassignment_create_events($wwassignment,$wwsetdata ) { -// error_log("enter create_events for set ".$wwassignment->name." id ".$wwassignment->id." date ".$wwsetdata['open_date']." ".$wwsetdata['due_date'] ); - global $COURSE; - //error_log("set data".print_r($wwsetdata,true)); + //global $COURSE; + global $CFG; + require_once("$CFG->dirroot/calendar/lib.php"); + traceLog("-----------------------Begin _wwassignment_create_events ---------------"); + traceLog(" create events for course: ". $wwassignment->name. + " assignment id ".$wwassignment->id." dates ". + $wwsetdata['open_date']." ".$wwsetdata['due_date'] ); + //$wwassignment->name is course name + //$wwassignment->id is name/id of set + debugLog("set data".print_r($wwsetdata,true)); if (! $opendate = $wwsetdata['open_date'] ) { -// error_log(" undefined open date "); + debugLog(" undefined open date "); } if (! $duedate = $wwsetdata["due_date"] ){ -// error_log(" undefined due date "); - } - if (! $wwassignmentid = $wwassignment->id ) { -// error_log(" undefined ww id "); - } - if (! $name = $wwassignment->name ) { -// error_log(" undefined set name "); - } - $courseid = $wwassignment->course; - - if (!$courseid) { - $courseid =$COURSE->id; - } - - - unset($event); - $event = new \stdClass(); - $event->name = $name; + debugLog(" undefined due date "); + } + if (! $wwassignmentid = $wwsetname = $wwassignment->id ) { + debugLog(" undefined set id/name "); + } + if (! $courseName = $wwassignment->name ) { + debugLog(" undefined course name "); + } + if (! $courseid = $wwassignment->id ) { + debugLog(" undefined course name "); + } + +// unset($event); + $event = new stdClass(); + $event->name = "$courseName $wwassignmentid"; $event->description = 'WeBWorK Set Event'; $event->courseid = $courseid; $event->groupid = 0; $event->userid = 0; - $event->format = 1; + //$event->format = 1; $event->modulename = 'wwassignment'; $event->instance = $wwassignmentid; $event->visible = 1; $event->eventtype = 'due'; $event->timestart = $duedate; - $event->timeduration = 1; - - // error_log("adding a due event"); + $event->timeduration = 0; + +// model +// $event = new stdClass; +// $event->name = get_string('stop', 'feedback').' '.$feedback->name; +// $event->description = format_module_intro('feedback', $feedback, $feedback->coursemodule); +// $event->courseid = $feedback->course; +// $event->groupid = 0; +// $event->userid = 0; +// $event->modulename = 'feedback'; +// $event->instance = $feedback->id; +// $event->eventtype = 'feedbackcloses'; // For activity module's events, this can be used to set the alternative text of the event icon. Set it to 'pluginname' unless you have a better string. +// $event->timestart = $feedback->timeclose; +// $event->visible = instance_is_visible('feedback', $feedback); +// $event->timeduration = 0; +// +// calendar_event::create($event); +// + debugLog("adding a due event"); $result = 0; - // $calendareventid = add_event($event); //calendar_event::create($event);// - global $CFG; - require_once("$CFG->dirroot/calendar/lib.php"); - $calendareventid = calendar_event::create($event); -// error_log("calendareventid $calendareventid created"); +// // $calendareventid = add_event($event); //calendar_event::create($event);// + +// FIXME -- this throws an error. ???? +// $calendareventid = calendar_event::create($event); + if(!$calendareventid) { -// error_log("can't create calendarevent for set $wwsetname wwid $wwassignmentid date $opendate $duedate course $courseid"); + debugLog("can't create calendarevent for set $wwsetname wwid $wwassignmentid date $opendate $duedate course $courseid"); $result = -1; + } else { + debugLog("created calendarevent for set $wwsetname wwid $wwassignmentid date $opendate $duedate course $courseid" + ); } + traceLog("-----------------------End _wwassignment_create_events ---------------"); return $result; } @@ -145,24 +178,272 @@ function _wwassignment_create_events($wwassignment,$wwsetdata ) { */ function _wwassignment_delete_events($wwassignmentid) { global $DB, $CFG; + traceLog("----------Begin _wwassignment_delete_events ---------------"); if ($events = $DB->get_records_select('event', "modulename = 'wwassignment' and instance = '$wwassignmentid'")) { foreach($events as $event) { - // error_log("deleting event ".$event->id); + debugLog("deleting event ".$event->id); require_once("$CFG->dirroot/calendar/lib.php"); $calEvent = new calendar_event($event); $calEvent->delete(true); - //delete_event($event->id); - + //delete_event($event->id); FIXME -- probably obsolete } } + traceLog("----------End _wwassignment_delete_events ---------------"); return 0; } +function _wwassignment_update_dirty_sets() { // update grades for all instances which have been modified since last cronjob + global $CFG,$DB; + global $CFG; + require_once($CFG->dirroot.'/course/lib.php'); + require_once($CFG->dirroot.'/report/log/locallib.php'); + require_once($CFG->libdir.'/adminlib.php'); + require_once($CFG->dirroot.'/lib/tablelib.php'); + traceLog("-----------------Begin _wwassignment_update_dirty_sets---------------"); + $timenow = time(); + ///////////////////////////////////////////////////////////////////// + // Obtain the last time that wwassignment cron processes were triggered. + ///////////////////////////////////////////////////////////////////// + $lastcron = $DB->get_field("modules","lastcron",array( "name"=>"wwassignment" )); + //FIXME make sure to readjust lastcron value + $lastcron = 1488778000; # so we get some examples + + debugLog("_wwassignment_update_dirty_sets: lastcron is $lastcron and time now is $timenow"); + + $logreader=''; + $logmanager = get_log_manager(); + $readers = $logmanager->get_readers(); + if (empty($logreader)) { + $reader = reset($readers); //default is \core\log\sql_internal_table_reader + } else { + $reader = $readers[$logreader]; + } + + if ($reader instanceof \core\log\sql_internal_table_reader) { + debugLog("wwassignment_update_dirty_sets: reader is instance of \core\log\sql_internal_table_reader" ); + } + + // If reader is not a sql_internal_table_reader and not legacy store then return. + if (!($reader instanceof \core\log\sql_internal_table_reader) && + !($reader instanceof logstore_legacy\log\store)) { + mtrace("wwassignment_update_dirty_sets:don't have access to the right kind of logs"); + debugLog("wwassignment_update_dirty_sets:bad logs "); + return array(); + } + ///////////////////////////////////////////////////////////////////// + // This is the legacy code, it imitates reading from the old log file + ///////////////////////////////////////////////////////////////////// + // $logRecords = get_logs("l.module LIKE \"wwassignment\" AND l.time >$lastcron ", null, "l.time ASC", $counter); + //// The "log" file contains relevent fields + //// time -- of record entry + //// course -- number of course targeted + //// module -- module targeted (e.g. wwassignment) + //// info -- contains the number of wwassignment record (the homework set targeted) + + ////////////////////////////////////////////////////// + //// legacy action: return the record for events targeting wwassignment + //// after the last cron run sorted by time in ascending order + ///////////////////////////////////////////////////// + + // foreach ($logRecords as $record) { + // $wwmodtimes[$wwid =$record->info] = $record->time; + // } + //// legacy action: create a hash $wwmodtimes with key= homework set (wwid), + //// value= last access to that homework set + //// Notice that a given homework set is likely to have been accessed multiple times + //// and this collapses all of those touches into a single reference + + // $idValues= implode(",", array_keys($wwmodtimes) ); + //// legacy action: Create an string with the wwid values ?? wouldn't an array have worked? + + // list($usql,$params) = $DB->get_in_or_equal($idValues); + + ////////////////////////////////////////////////////////////////// + //// legacy action: result is a string $usql (sic) of the form + //// "IN (?,?,?)" and $params an array [23,12,45] + //// where the numbers are wwid's + ////////////////////////////////////////////////////////////////// + + +// $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid, cm.id as wwinstanceid " . +// "FROM {wwassignment} a, {course_modules} cm, {modules} m WHERE m.name = 'wwassignment' " . +// "AND m.id=cm.module AND cm.instance=a.id AND a.id $usql"; +// $rs = $DB->get_recordset_sql($sql,$params)) + + + ///////////////////////////////// ///////////////////////////////// + // Begin finding all of the wwassignment modules that have been touched since the last cron update + ///////////////////////////////// ///////////////////////////////// + + ////////////////////////////////////////////////////////////////// + //// legacy action: select records from wwassignment with id's in $insql (or $usql (sic)) + //// -- and which therefore have been touched since the last cron update + //// join each of these with the record in course_module which references (cm.instance) the record in wwassignmnent + //// and join each these also with the record in modules referenced from course_modules (cm.module). + //// Return the complete wwassignment record, augmented with the course_module idnumber (has inconsistent data) + //// the courseid (a number) and the course_module record id (cm.id) + ////////////////////////////////////////////////////////////////// + + + if ($reader instanceof logstore_legacy\log\store) { + debugLog("wwassignment_update_dirty_sets:Reading from the old style logs"); + $logtable = 'log'; + $timefield = 'time'; + $coursefield = 'course'; + // Anonymous actions are never logged in legacy log. + $nonanonymous = ''; + } else { + $logtable = $reader->get_internal_log_table_name(); + $timefield = 'timecreated'; + $coursefield = 'courseid'; + $nonanonymous = 'AND anonymous = 0'; + } + +// +// $courseselect = ''; +// if ($courseid) { +// $courseselect = "AND $coursefield = :courseid"; +// $params['courseid'] = $courseid; +// } + +#################### +# Look for activity involving wwassignment in the general log file +#################### + $params['module_type'] = 'course_module'; + $params['wwassignment'] = 'wwassignment'; + debugLog("using the log table $logtable"); + +// // Could we speed this up by getting all of the log records pertaining to webwork in one go? +// // Or perhaps just the log records which have occured after the lastcron date +// // Then create a hash with wwassignment->id => timemodified +// // means just one database lookup +// $counter = 0; +// // this is most likely what needs to be replaced +// +// +// // $logRecords = get_logs("l.module LIKE \"wwassignment\" AND l.time >$lastcron ", null, "l.time ASC", $counter,''); + +////////////////////////////////////////////////////////// +// reproducing legacy effect with the call to the "log" table +////////////////////////////////////////////////////////// +// Find all event records which have been created since the last cron update and which +// target a module +// AND the module table is labeled "wwassignment". +// return the time, the courseid, event id, +// the objecttable (named wwassign), and +// the target (module_type) +// !! the objectid (which wwassignment was touched) + + $logRecords = $DB->get_records_sql("SELECT $timefield AS time, COUNT(*) AS num, + $coursefield AS courseid, target AS target, + objecttable AS module, + objectid AS wwassignmentid, + id AS eventid + FROM {" . $logtable . "} + WHERE $timefield > $lastcron + AND target = :module_type + AND objecttable = :wwassignment + GROUP BY $timefield", $params); + $number_of_log_records = count($logRecords); + debugLog("wwassignment_update_dirty_sets:number of logRecords $number_of_log_records"); + //debugLog(print_r($logRecords,true)); + + + + $wwmodtimes=array(); + foreach ($logRecords as $record) { + $wwmodtimes[$record->wwassignmentid] = $record->time; + } + +// +// // Create an array with the wwid values +// $idValues= implode(",", array_keys($wwmodtimes) ); +// //list($insql,$inparams) = $DB->get_in_or_equal($idValues,SQL_PARAMS_NAMED); + $arraykeys = array_keys($wwmodtimes); +// //debugLog("array_keys ".print_r($arraykeys,true)); + list($insql,$inparams) = $DB->get_in_or_equal($arraykeys,SQL_PARAMS_NAMED); +// //list($insql, $inparams) = $DB->get_in_or_equal($wwmodtimes,SQL_PARAMS_NAMED); +// debugLog("values string: $idValues"); +// debugLog("last modification times".print_r($wwmodtimes,true)); + //debugLog("insql ".print_r($insql,true)); + //debugLog("array values".print_r(array_values($arraykeys),true)); + debugLog("inparams ".print_r($inparams, true)); + + + ///////////////////////////////// ///////////////////////////////// + // End finding all of the wwassignment modules that have been touched since the last cron update + ///////////////////////////////// ///////////////////////////////// + // $insql looks like "IN(4,6,78)" where the numbers are ids (a.id) + // of records in the wwassignment table + // these are records of homework sets that have been touched. + // + + ////////////////////////////////////////////////////////////////// + // construct query for wwassignment table + ///////////////////////////////////////////////////////////////// + + // This should be the same query for both the legacy code + // and the new code + + $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid, + cm.id as wwinstanceid " . + "FROM {wwassignment} a, + {course_modules} cm, + {modules} m + WHERE a.id $insql + AND cm.instance=a.id + AND m.id=cm.module + AND m.name = 'wwassignment' + "; + debugLog("sql obtained from wwassignment is $sql"); + $rs = $DB->get_recordset_sql($sql,$inparams); + +///////////////////////////////// +// + if ($rs = $DB->get_recordset_sql($sql,$inparams)) { + foreach ( $rs as $wwassignment ) { + debugLog("record set ".print_r($wwassignment, true)); + if (!$wwassignment->cmidnumber) { // is this ever needed? + $wwassignment->cmidnumber =_wwassignment_cmid() ; + } + $wwassignment->timemodified = $wwmodtimes[$wwassignment->id]; + if ($wwassignment->timemodified > $lastcron) { + debugLog("instance needs update. timemodified ".$wwassignment->timemodified. + ", lastcron $lastcron, course id ".$wwassignment->course.",\n wwassignment id ".$wwassignment->id. + ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid. + ", grade ".$wwassignment->grade); + if (1) { //FIXME this should check something + wwassignment_update_grades($wwassignment); + debugLog("update entire set ".print_r($wwassignment, true ) ); + + } else { + debugLog("do wwassignment_grade_item_update" ); + wwassignment_grade_item_update($wwassignment); + + } + +// // refresh events for this assignment + _wwassignment_refresh_event($wwassignment); +// + } else { // ?? shouldn't every record with id in $usql need an update? why the extra check. + debugLog("no update needed. timemodified ".$wwassignment->timemodified. + ", lastcron $lastcron, course id ".$wwassignment->course.", wwassignment id ".$wwassignment->id. + ", set name ".$wwassignment->name.", cm.id ".$wwassignment->wwinstanceid); + } + + } + $rs->close(); + } + traceLog("-----------------End _wwassignment_update_dirty_sets---------------"); + return(true); +} + function _wwassignment_refresh_event($wwassignment) { global $DB; + traceLog("----------------Begin _wwassignment_refresh_event-------------"); $cid = $wwassignment->course; $wwcoursename = _wwassignment_mapped_course($cid,false); if ( $wwcoursename== -1) { @@ -171,7 +452,7 @@ function _wwassignment_refresh_event($wwassignment) { } $wwclient = new wwassignment_client(); $wwsetname = $wwassignment->webwork_set; - error_log("updating events for $wwcoursename $wwsetname"); + traceLog("updating events for course: $wwcoursename assignment: $wwsetname"); //get data from WeBWorK $wwsetdata = $wwclient->get_assignment_data($wwcoursename,$wwsetname,false); $wwassignment->grade = $wwclient->get_max_grade($wwcoursename,$wwsetname,false); @@ -180,6 +461,7 @@ function _wwassignment_refresh_event($wwassignment) { // update event _wwassignment_delete_events($wwassignment->id); _wwassignment_create_events($wwassignment,$wwsetdata); + traceLog("----------------End _wwassignment_refresh_event-------------"); return true; } From 9aa35ec33beb316a630970176031dda5dfe96fd1 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sat, 11 Mar 2017 21:36:50 -0500 Subject: [PATCH 06/10] =?UTF-8?q?small=20changes=20=E2=80=94=20trying=20fi?= =?UTF-8?q?gure=20out=20why=20calendar=5Fevent::create=20fails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locallib.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/locallib.php b/locallib.php index 6ed0183..5310f09 100644 --- a/locallib.php +++ b/locallib.php @@ -1,8 +1,8 @@ libdir/soap/nusoap.php"); require_once("$CFG->libdir/soaplib.php"); - +require_once("$CFG->dirroot/calendar/lib.php"); + define('WWASSIGNMENT_DEBUG',0); // define('WWASSIGNMENT_DEBUG',1); //define('WWASSIGNMENT_TRACE',0); @@ -128,7 +128,7 @@ function _wwassignment_create_events($wwassignment,$wwsetdata ) { $event->courseid = $courseid; $event->groupid = 0; $event->userid = 0; - //$event->format = 1; + $event->format = 1; $event->modulename = 'wwassignment'; $event->instance = $wwassignmentid; $event->visible = 1; @@ -152,13 +152,18 @@ function _wwassignment_create_events($wwassignment,$wwsetdata ) { // // calendar_event::create($event); // - debugLog("adding a due event"); + traceLog("adding a due event"); $result = 0; + //global $CFG; + require_once("$CFG->dirroot/calendar/lib.php"); + // // $calendareventid = add_event($event); //calendar_event::create($event);// // FIXME -- this throws an error. ???? -// $calendareventid = calendar_event::create($event); + + //$calendareventid = calendar_event::create($event); + traceLog("due event added"); if(!$calendareventid) { debugLog("can't create calendarevent for set $wwsetname wwid $wwassignmentid date $opendate $duedate course $courseid"); $result = -1; From 63e8210cdbdc6b78bb1c6175272ea88a7c621df7 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sun, 12 Mar 2017 22:54:44 -0400 Subject: [PATCH 07/10] Fix problem with calendar event (the coursed was incorrectly defined). Set debug switches to zero for now. --- locallib.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locallib.php b/locallib.php index 5310f09..963a0d3 100644 --- a/locallib.php +++ b/locallib.php @@ -5,8 +5,8 @@ define('WWASSIGNMENT_DEBUG',0); // define('WWASSIGNMENT_DEBUG',1); -//define('WWASSIGNMENT_TRACE',0); - define('WWASSIGNMENT_TRACE',1); +define('WWASSIGNMENT_TRACE',0); +//define('WWASSIGNMENT_TRACE',1); ////////////////////////////////////////////////////////////////// @@ -117,8 +117,8 @@ function _wwassignment_create_events($wwassignment,$wwsetdata ) { if (! $courseName = $wwassignment->name ) { debugLog(" undefined course name "); } - if (! $courseid = $wwassignment->id ) { - debugLog(" undefined course name "); + if (! $courseid = $wwassignment->course) { + debugLog(" undefined course id "); } // unset($event); @@ -162,7 +162,7 @@ function _wwassignment_create_events($wwassignment,$wwsetdata ) { // FIXME -- this throws an error. ???? - //$calendareventid = calendar_event::create($event); + $calendareventid = calendar_event::create($event); traceLog("due event added"); if(!$calendareventid) { debugLog("can't create calendarevent for set $wwsetname wwid $wwassignmentid date $opendate $duedate course $courseid"); From b7019f5dd9fce234848eb42f69fd2b92d120a44b Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Mon, 13 Mar 2017 11:33:02 -0400 Subject: [PATCH 08/10] =?UTF-8?q?Restore=20proper=20initialization=20of=20?= =?UTF-8?q?$lastcron=20=E2=80=94=20the=20last=20time=20the=20cron=20progra?= =?UTF-8?q?m=20was=20run.=20Update=20descriptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib.php | 86 +++++++++++++++++++++++++--------------------------- locallib.php | 2 +- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/lib.php b/lib.php index 7809796..d1144b6 100644 --- a/lib.php +++ b/lib.php @@ -4,44 +4,37 @@ // debug switch defined in locallib.php define('WWASSIGNMENT_DEBUG',0); -//////////////////////////////////////////////////////////////// -// External grade triggers -// wwassignment_update_grades(wwassignment,userid=0) is called from -// grade_update_mod_grades in gradlib.php and also from wwassignment/upgrade.php file -// grade_update_mod_grades is called by $grade_item->refresh_grades -// -// wwassignment_grade_item_update(wwassignment) -// is called from grade_update_mod_grades (before update_grades(wwassignment,userid=0))) -// -// wwassignment_get_user_grades -// could be called from wwassignment/index.php pages (legacy??) -// -// High level grade calls in gradelib.php (see end of file) -// -// +/** ///////////////////////////////////////////////////////////// +* External grade triggers +* 1. wwassignment_update_grades(wwassignment,userid=0) is called from +* grade_update_mod_grades in gradlib.php and also from wwassignment/upgrade.php file +* grade_update_mod_grades is called by $grade_item->refresh_grades +* * handles updating the actual grades +* 2. wwassignment_grade_item_update(wwassignment) +* is called from grade_update_mod_grades (before update_grades(wwassignment,userid=0))) +* * updates the items (e.g. homework sets) that are graded +* +* High level grade calls are in gradelib.php (see end of file) +*/ // + // Internal grade calling structure // -// wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=true) -- updates grades for assignment instance or all instances -// wwassignment_get_user_grades($wwassignment,$userid=0) -- fetches homework grades from WeBWorK -// _wwassignment_get_course_students($courseid) -- collects users from moodle database -// $wwclient->grade_users_sets($webworkcourse,$webworkusers,$webworkset) -- fetches grades from a given course, set and user collection -// wwassignment_grade_item_update(wwassignment, grades) +// 1. wwassignment_update_grades($wwassignment=null, $userid=0, $nullifnone=true) +// -- updates grades for assignment instance or all instances +// * wwassignment_get_user_grades($wwassignment,$userid=0) +// -- fetches homework grades from WeBWorK +// * _wwassignment_get_course_students($courseid) -- collects users from moodle database +// * $wwclient->grade_users_sets($webworkcourse,$webworkusers,$webworkset) +// -- fetches grades from a given course, set and user collection +// 2. wwassignment_grade_item_update(wwassignment, grades) // grade_update(...) -- fills record in grade_item table and possibly in grade_grades table as well // -// wwassignment_update_grade_item(wwassignment) -- just updates grade_item table -// wwassignment_update_grade_item(wwassignment, grades) updates grade_item table and grade_grades table //////////////////////////////////////////////////////////////// - -// not sure why this function is still here. +// This functino is defined in gradeslib.php -- I believe // function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL) { +//////////////////////////////////////////////////////////////// -/** - * Refetches data from all course activities - * @param int $courseid - * @param string $modname - * @return success - */ //////////////////////////////////////////////////////////////// @@ -691,10 +684,11 @@ function wwassignment_refresh_events($courseid = 0) { // return true; // } - +/////////////////////////////////////////////////////////////////////////////////////// // High level grade calls ins gradelib.php +/////////////////////////////////////////////////////////////////////////////////////// -/** +/** A. * Returns grading information for given activity - optionally with users grades * Manual, course or category items can not be queried. * @public @@ -706,10 +700,10 @@ function wwassignment_refresh_events($courseid = 0) { * @return array of grade information objects (scaleid, name, grade and locked status, etc.) indexed with itemnumbers */ -// function grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=null) { +// A. function grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=null) { - /** + /** B. * Submit new or update grade; update/create grade_item definition. Grade must have userid specified, * rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property * or key means do not change existing. @@ -728,15 +722,19 @@ function wwassignment_refresh_events($courseid = 0) { * @param mixed $grades grade (object, array) or several grades (arrays of arrays or objects), NULL if updating grade_item definition only * @param mixed $itemdetails object or array describing the grading item, NULL if no change */ -// function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL) { - -/** - * Refetches data from all course activities - * @param int $courseid - * @param string $modname - * @return success - */ -// function grade_grab_course_grades($courseid, $modname=null) { + +/** +* B. function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, +* $itemnumber, $grades=NULL, $itemdetails=NULL) {} + +/** C. +* Refetches data from all course activities +* @param int $courseid +* @param string $modname +* @return success +* C. function grade_grab_course_grades($courseid, $modname=null) {} +*/ +/////////////////////////////////////////////////////////////////////////////////////// function wwassignment_supports($feature) { switch($feature) { @@ -748,7 +746,7 @@ function wwassignment_supports($feature) { /** - * Given a coursemodule object, this function returns the extra + * Given a coursemodule object, `wwassignment_get_coursemodule_info` function returns the extra * information needed to print this activity in various places. * * If folder needs to be displayed inline we store additional information diff --git a/locallib.php b/locallib.php index 963a0d3..be6f010 100644 --- a/locallib.php +++ b/locallib.php @@ -211,7 +211,7 @@ function _wwassignment_update_dirty_sets() { // update grades for all instances ///////////////////////////////////////////////////////////////////// $lastcron = $DB->get_field("modules","lastcron",array( "name"=>"wwassignment" )); //FIXME make sure to readjust lastcron value - $lastcron = 1488778000; # so we get some examples + // $lastcron = 1488778000; # so we get some examples debugLog("_wwassignment_update_dirty_sets: lastcron is $lastcron and time now is $timenow"); From e8dbb2ef5a70fa60cd78dc6b4b95aabd20060cb9 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Mon, 13 Mar 2017 11:34:09 -0400 Subject: [PATCH 09/10] Restore cron to run every 300 seconds (every five minutes). --- version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.php b/version.php index 87a8dbc..c99f386 100644 --- a/version.php +++ b/version.php @@ -26,7 +26,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->version = 2015030918; // The current module version (Date: YYYYMMDDXX) $plugin->requires = 2014110400; // Requires this Moodle version -$plugin->cron = 10; // Period for cron to check this module (secs) -- every 5 minutes +$plugin->cron = 300; // Period for cron to check this module (secs) -- every 5 minutes $plugin->component = 'mod_wwassignment'; $plugin->maturity = MATURITY_STABLE; From d634eb60db494974f4667af94c7002ca1a786203 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Mon, 12 Jun 2017 09:47:37 -0400 Subject: [PATCH 10/10] Add protection against the case where there are no grades that need updating. --- locallib.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locallib.php b/locallib.php index be6f010..98bbbdd 100644 --- a/locallib.php +++ b/locallib.php @@ -4,7 +4,7 @@ require_once("$CFG->dirroot/calendar/lib.php"); define('WWASSIGNMENT_DEBUG',0); -// define('WWASSIGNMENT_DEBUG',1); +//define('WWASSIGNMENT_DEBUG',1); define('WWASSIGNMENT_TRACE',0); //define('WWASSIGNMENT_TRACE',1); @@ -366,7 +366,14 @@ function _wwassignment_update_dirty_sets() { // update grades for all instances // //list($insql,$inparams) = $DB->get_in_or_equal($idValues,SQL_PARAMS_NAMED); $arraykeys = array_keys($wwmodtimes); // //debugLog("array_keys ".print_r($arraykeys,true)); + if (count( $arraykeys)==0) { + traceLog("-----------------no grades to update -------------------------------"); + traceLog("-----------------End _wwassignment_update_dirty_sets---------------"); + return true; + } + traceLog("------ find arraykeys in SQL_PARAMs_NAMEd"); list($insql,$inparams) = $DB->get_in_or_equal($arraykeys,SQL_PARAMS_NAMED); + // //list($insql, $inparams) = $DB->get_in_or_equal($wwmodtimes,SQL_PARAMS_NAMED); // debugLog("values string: $idValues"); // debugLog("last modification times".print_r($wwmodtimes,true));