function import_xml_grades($text, $course, &$error) { global $USER; $importcode = get_new_importcode(); $status = true; $content = xmlize($text); if (!empty($content['results']['#']['result'])) { $results = $content['results']['#']['result']; foreach ($results as $i => $result) { $gradeidnumber = $result['#']['assignment'][0]['#']; if (!($grade_items = grade_item::fetch_all(array('idnumber' => $gradeidnumber, 'courseid' => $course->id)))) { // gradeitem does not exist // no data in temp table so far, abort $status = false; $error = get_string('errincorrectgradeidnumber', 'gradeimport_xml', $gradeidnumber); break; } else { if (count($grade_items) != 1) { $status = false; $error = get_string('errduplicategradeidnumber', 'gradeimport_xml', $gradeidnumber); break; } else { $grade_item = reset($grade_items); } } // grade item locked, abort if ($grade_item->is_locked()) { $status = false; $error = get_string('gradeitemlocked', 'grades'); break; } // check if user exist and convert idnumber to user id $useridnumber = $result['#']['student'][0]['#']; if (!($user = get_record('user', 'idnumber', addslashes($useridnumber)))) { // no user found, abort $status = false; $error = get_string('errincorrectuseridnumber', 'gradeimport_xml', $useridnumber); break; } // check if grade_grade is locked and if so, abort if ($grade_grade = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $user->id))) { $grade_grade->grade_item =& $grade_item; if ($grade_grade->is_locked()) { // individual grade locked, abort $status = false; $error = get_string('gradegradeslocked', 'grades'); break; } } $newgrade = new object(); $newgrade->itemid = $grade_item->id; $newgrade->userid = $user->id; $newgrade->importcode = $importcode; $newgrade->importer = $USER->id; // check grade value exists and is a numeric grade if (isset($result['#']['score'][0]['#'])) { if (is_numeric($result['#']['score'][0]['#'])) { $newgrade->finalgrade = $result['#']['score'][0]['#']; } else { $status = false; $error = get_string('badgrade', 'grades'); break; } } else { $newgrade->finalgrade = NULL; } // check grade feedback exists if (isset($result['#']['feedback'][0]['#'])) { $newgrade->feedback = $result['#']['feedback'][0]['#']; } else { $newgrade->feedback = NULL; } // insert this grade into a temp table if (!insert_record('grade_import_values', addslashes_recursive($newgrade))) { $status = false; // could not insert into temp table $error = get_string('importfailed', 'grades'); break; } } } else { // no results section found in xml, // assuming bad format, abort import $status = false; $error = get_string('errbadxmlformat', 'gradeimport_xml'); } if ($status) { return $importcode; } else { import_cleanup($importcode); return false; } }
/** * given an import code, commits all entries in buffer tables * (grade_import_value and grade_import_newitem) * If this function is called, we assume that all data collected * up to this point is fine and we can go ahead and commit * @param int courseid - id of the course * @param string importcode - import batch identifier * @param feedback print feedback and continue button * @return bool success */ function grade_import_commit($courseid, $importcode, $importfeedback = true, $verbose = true) { global $CFG, $USER, $DB; $commitstart = time(); // start time in case we need to roll back $newitemids = array(); // array to hold new grade_item ids from grade_import_newitem table, mapping array /// first select distinct new grade_items with this batch $params = array($importcode, $USER->id); if ($newitems = $DB->get_records_sql("SELECT *\n FROM {grade_import_newitem}\n WHERE importcode = ? AND importer=?", $params)) { // instances of the new grade_items created, cached // in case grade_update fails, so that we can remove them $instances = array(); $failed = false; foreach ($newitems as $newitem) { // get all grades with this item if ($grades = $DB->get_records('grade_import_values', array('newgradeitem' => $newitem->id))) { /// create a new grade item for this - must use false as second param! /// TODO: we need some bounds here too $gradeitem = new grade_item(array('courseid' => $courseid, 'itemtype' => 'manual', 'itemname' => $newitem->itemname), false); $gradeitem->insert('import'); $instances[] = $gradeitem; // insert each individual grade to this new grade item foreach ($grades as $grade) { if (!$gradeitem->update_final_grade($grade->userid, $grade->finalgrade, 'import', $grade->feedback, FORMAT_MOODLE)) { $failed = true; break 2; } } } } if ($failed) { foreach ($instances as $instance) { $gradeitem->delete('import'); } import_cleanup($importcode); return false; } } /// then find all existing items if ($gradeitems = $DB->get_records_sql("SELECT DISTINCT (itemid)\n FROM {grade_import_values}\n WHERE importcode = ? AND importer=? AND itemid > 0", array($importcode, $USER->id))) { $modifieditems = array(); foreach ($gradeitems as $itemid => $notused) { if (!($gradeitem = new grade_item(array('id' => $itemid)))) { // not supposed to happen, but just in case import_cleanup($importcode); return false; } // get all grades with this item if ($grades = $DB->get_records('grade_import_values', array('itemid' => $itemid))) { // make the grades array for update_grade foreach ($grades as $grade) { if (!$importfeedback) { $grade->feedback = false; // ignore it } if (!$gradeitem->update_final_grade($grade->userid, $grade->finalgrade, 'import', $grade->feedback)) { $failed = 1; break 2; } } //$itemdetails -> idnumber = $gradeitem->idnumber; $modifieditems[] = $itemid; } if (!empty($failed)) { import_cleanup($importcode); return false; } } } if ($verbose) { notify(get_string('importsuccess', 'grades'), 'notifysuccess'); $unenrolledusers = get_unenrolled_users_in_import($importcode, $courseid); if ($unenrolledusers) { $list = "<ul>\n"; foreach ($unenrolledusers as $u) { $u->fullname = fullname($u); $list .= '<li>' . get_string('usergrade', 'grades', $u) . '</li>'; } $list .= "</ul>\n"; notify(get_string('unenrolledusersinimport', 'grades', $list), 'notifysuccess'); } print_continue($CFG->wwwroot . '/grade/index.php?id=' . $courseid); } // clean up import_cleanup($importcode); return true; }
function import_account(&$a, $file) { logger("Start user import from " . $file['tmp_name']); /* STEPS 1. checks 2. replace old baseurl with new baseurl 3. import data (look at user id and contacts id) 4. archive non-dfrn contacts 5. send message to dfrn contacts */ $account = json_decode(file_get_contents($file['tmp_name']), true); if ($account === null) { notice(t("Error decoding account file")); return; } if (!x($account, 'version')) { notice(t("Error! No version data in file! This is not a Friendica account file?")); return; } /* // this is not required as we remove columns in json not in current db schema if ($account['schema'] != DB_UPDATE_VERSION) { notice(t("Error! I can't import this file: DB schema version is not compatible.")); return; } */ // check for username $r = q("SELECT uid FROM user WHERE nickname='%s'", $account['user']['nickname']); if ($r === false) { logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL); notice(t('Error! Cannot check nickname')); return; } if (count($r) > 0) { notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname'])); return; } // check if username matches deleted account $r = q("SELECT id FROM userd WHERE username='******'", $account['user']['nickname']); if ($r === false) { logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL); notice(t('Error! Cannot check nickname')); return; } if (count($r) > 0) { notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname'])); return; } $oldbaseurl = $account['baseurl']; $newbaseurl = $a->get_baseurl(); $olduid = $account['user']['uid']; unset($account['user']['uid']); unset($account['user']['account_expired']); unset($account['user']['account_expires_on']); unset($account['user']['expire_notification_sent']); foreach ($account['user'] as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); } // import user $r = db_import_assoc('user', $account['user']); if ($r === false) { //echo "<pre>"; var_dump($r, $query, mysql_error()); killme(); logger("uimport:insert user : ERROR : " . last_error(), LOGGER_NORMAL); notice(t("User creation error")); return; } $newuid = last_insert_id(); //~ $newuid = 1; foreach ($account['profile'] as &$profile) { foreach ($profile as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); foreach (array("profile", "avatar") as $k) { $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v); } } $profile['uid'] = $newuid; $r = db_import_assoc('profile', $profile); if ($r === false) { logger("uimport:insert profile " . $profile['profile-name'] . " : ERROR : " . last_error(), LOGGER_NORMAL); info(t("User profile creation error")); import_cleanup($newuid); return; } } $errorcount = 0; foreach ($account['contact'] as &$contact) { if ($contact['uid'] == $olduid && $contact['self'] == '1') { foreach ($contact as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); foreach (array("profile", "avatar", "micro") as $k) { $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v); } } } if ($contact['uid'] == $olduid && $contact['self'] == '0') { // set contacts 'avatar-date' to "0000-00-00 00:00:00" to let poller to update urls $contact["avatar-date"] = "0000-00-00 00:00:00"; switch ($contact['network']) { case NETWORK_DFRN: // send relocate message (below) break; case NETWORK_ZOT: // TODO handle zot network break; case NETWORK_MAIL2: // TODO ? break; case NETWORK_FEED: case NETWORK_MAIL: // Nothing to do break; default: // archive other contacts $contact['archive'] = "1"; } } $contact['uid'] = $newuid; $r = db_import_assoc('contact', $contact); if ($r === false) { logger("uimport:insert contact " . $contact['nick'] . "," . $contact['network'] . " : ERROR : " . last_error(), LOGGER_NORMAL); $errorcount++; } else { $contact['newid'] = last_insert_id(); } } if ($errorcount > 0) { notice(sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount)); } foreach ($account['group'] as &$group) { $group['uid'] = $newuid; $r = db_import_assoc('group', $group); if ($r === false) { logger("uimport:insert group " . $group['name'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } else { $group['newid'] = last_insert_id(); } } foreach ($account['group_member'] as &$group_member) { $group_member['uid'] = $newuid; $import = 0; foreach ($account['group'] as $group) { if ($group['id'] == $group_member['gid'] && isset($group['newid'])) { $group_member['gid'] = $group['newid']; $import++; break; } } foreach ($account['contact'] as $contact) { if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) { $group_member['contact-id'] = $contact['newid']; $import++; break; } } if ($import == 2) { $r = db_import_assoc('group_member', $group_member); if ($r === false) { logger("uimport:insert group member " . $group_member['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } } foreach ($account['photo'] as &$photo) { $photo['uid'] = $newuid; $photo['data'] = hex2bin($photo['data']); $p = new Photo($photo['data'], $photo['type']); $r = $p->store($photo['uid'], $photo['contact-id'], $photo['resource-id'], $photo['filename'], $photo['album'], $photo['scale'], $photo['profile'], $photo['allow_cid'], $photo['allow_gid'], $photo['deny_cid'], $photo['deny_gid']); if ($r === false) { logger("uimport:insert photo " . $photo['resource-id'] . "," . $photo['scale'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } foreach ($account['pconfig'] as &$pconfig) { $pconfig['uid'] = $newuid; $r = db_import_assoc('pconfig', $pconfig); if ($r === false) { logger("uimport:insert pconfig " . $pconfig['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } // send relocate messages proc_run('php', 'include/notifier.php', 'relocate', $newuid); info(t("Done. You can now login with your username and password")); goaway($a->get_baseurl() . "/login"); }
if ($separatemode and !groups_is_member($currentgroup, $studentid)) { // not allowed to import into this group, abort $status = false; import_cleanup($importcode); echo $OUTPUT->notification('user not member of current group, can not update!'); break; } // insert results of this students into buffer if ($status and !empty($newgrades)) { foreach ($newgrades as $newgrade) { // check if grade_grade is locked and if so, abort if (!empty($newgrade->itemid) and $grade_grade = new grade_grade(array('itemid' => $newgrade->itemid, 'userid' => $studentid))) { if ($grade_grade->is_locked()) { // individual grade locked $status = false; import_cleanup($importcode); echo $OUTPUT->notification(get_string('gradelocked', 'grades')); break 2; } } $newgrade->importcode = $importcode; $newgrade->userid = $studentid; $newgrade->importer = $USER->id; $DB->insert_record('grade_import_values', $newgrade); } } // updating/inserting all comments here if ($status and !empty($newfeedbacks)) { foreach ($newfeedbacks as $newfeedback) { $sql = "SELECT *\n FROM {grade_import_values}\n WHERE importcode=? AND userid=? AND itemid=? AND importer=?"; if ($feedback = $DB->get_record_sql($sql, array($importcode, $studentid, $newfeedback->itemid, $USER->id))) {
/** * Clean up failed CSV grade import. Clears the temp table for inserting grades. * * @param string $notification The error message to display from the unsuccessful grade import. */ protected function cleanup_import($notification) { $this->status = false; import_cleanup($this->importcode); $this->gradebookerrors[] = $notification; }