/** * Update a record in a table * * $dataobject is an object containing needed data * Relies on $dataobject having a variable "id" to * specify the record to update * * @uses $CFG * @uses $db * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @return bool */ function update_record($table, $dataobject) { global $db, $CFG; if (!isset($dataobject->id)) { return false; } /// Check we are handling a proper $dataobject if (is_array($dataobject)) { debugging('Warning. Wrong call to update_record(). $dataobject must be an object. array found instead', DEBUG_DEVELOPER); $dataobject = (object) $dataobject; } // Remove this record from record cache since it will change if (!empty($CFG->rcache)) { // no === here! breaks upgrade rcache_unset($table, $dataobject->id); } /// Temporary hack as part of phasing out all access to obsolete user tables XXX if (!empty($CFG->rolesactive)) { if (in_array($table, array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins'))) { if (debugging()) { var_dump(debug_backtrace()); } error('This SQL relies on obsolete tables (' . $table . ')! Your code must be fixed by a developer.'); } } /// Begin DIRTY HACK if ($CFG->dbfamily == 'oracle') { oracle_dirty_hack($table, $dataobject); // Convert object to the correct "empty" values for Oracle DB } /// End DIRTY HACK /// Under Oracle, MSSQL and PostgreSQL we have our own update record process /// detect all the clob/blob fields and delete them from the record being updated /// saving them into $foundclobs and $foundblobs [$fieldname]->contents /// They will be updated later if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') && !empty($dataobject->id)) { /// Detect lobs $foundclobs = array(); $foundblobs = array(); db_detect_lobs($table, $dataobject, $foundclobs, $foundblobs, true); } // Determine all the fields in the table if (!($columns = $db->MetaColumns($CFG->prefix . $table))) { return false; } $data = (array) $dataobject; if (defined('MDL_PERFDB')) { global $PERF; $PERF->dbqueries++; } // Pull out data matching these fields $ddd = array(); foreach ($columns as $column) { if ($column->name != 'id' and array_key_exists($column->name, $data)) { $ddd[$column->name] = $data[$column->name]; } } // Construct SQL queries $numddd = count($ddd); $count = 0; $update = ''; /// Only if we have fields to be updated (this will prevent both wrong updates + /// updates of only LOBs in Oracle if ($numddd) { foreach ($ddd as $key => $value) { $count++; if ($value === NULL) { $update .= $key . ' = NULL'; // previously NULLs were not updated } else { $update .= $key . ' = \'' . $value . '\''; // All incoming data is already quoted } if ($count < $numddd) { $update .= ', '; } } if (!($rs = $db->Execute('UPDATE ' . $CFG->prefix . $table . ' SET ' . $update . ' WHERE id = \'' . $dataobject->id . '\''))) { debugging($db->ErrorMsg() . '<br /><br />UPDATE ' . $CFG->prefix . $table . ' SET ' . s($update) . ' WHERE id = \'' . $dataobject->id . '\''); if (!empty($CFG->dblogerror)) { $debug = array_shift(debug_backtrace()); error_log("SQL " . $db->ErrorMsg() . " in {$debug['file']} on line {$debug['line']}. STATEMENT: UPDATE {$CFG->prefix}{$table} SET {$update} WHERE id = '{$dataobject->id}'"); } return false; } } /// Under Oracle, MSSQL and PostgreSQL, finally, update all the Clobs and Blobs present in the record /// if we know we have some of them in the query if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') && !empty($dataobject->id) && (!empty($foundclobs) || !empty($foundblobs))) { if (!db_update_lobs($table, $dataobject->id, $foundclobs, $foundblobs)) { return false; //Some error happened while updating LOBs } } return true; }
/** * Update a record in a table * * $dataobject is an object containing needed data * Relies on $dataobject having a variable "id" to * specify the record to update * * @uses $CFG * @uses $db * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @return bool */ function update_record($table, $dataobject) { global $db, $CFG; // integer value in id propery required if (empty($dataobject->id)) { return false; } $dataobject->id = (int) $dataobject->id; /// Check we are handling a proper $dataobject if (is_array($dataobject)) { debugging('Warning. Wrong call to update_record(). $dataobject must be an object. array found instead', DEBUG_DEVELOPER); $dataobject = (object) $dataobject; } else { if (is_object($dataobject)) { // make sure there are no properties or private methods because we cast to array later, // at the same time this undos the object references so that PHP 5 works the same as PHP 4, // the main reason for this is BC after the dirty magic hack introduction if ($properties = get_object_vars($dataobject)) { $dataobject = (object) $properties; } unset($properties); } } /// Extra protection against SQL injections foreach ((array) $dataobject as $k => $v) { $dataobject->{$k} = sql_magic_quotes_hack($v); } // Remove this record from record cache since it will change if (!empty($CFG->rcache)) { // no === here! breaks upgrade rcache_unset($table, $dataobject->id); } /// Temporary hack as part of phasing out all access to obsolete user tables XXX if (!empty($CFG->rolesactive)) { if (in_array($table, array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins'))) { if (debugging()) { var_dump(debug_backtrace()); } error('This SQL relies on obsolete tables (' . $table . ')! Your code must be fixed by a developer.'); } } /// Begin DIRTY HACK if ($CFG->dbfamily == 'oracle') { oracle_dirty_hack($table, $dataobject); // Convert object to the correct "empty" values for Oracle DB } /// End DIRTY HACK /// Under Oracle, MSSQL and PostgreSQL we have our own update record process /// detect all the clob/blob fields and delete them from the record being updated /// saving them into $foundclobs and $foundblobs [$fieldname]->contents /// They will be updated later if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') && !empty($dataobject->id)) { /// Detect lobs $foundclobs = array(); $foundblobs = array(); db_detect_lobs($table, $dataobject, $foundclobs, $foundblobs, true); } // Determine all the fields in the table if (!($columns = $db->MetaColumns($CFG->prefix . $table))) { return false; } $data = (array) $dataobject; if (defined('MDL_PERFDB')) { global $PERF; $PERF->dbqueries++; } // Pull out data matching these fields $update = array(); foreach ($columns as $column) { if ($column->name == 'id') { continue; } if (array_key_exists($column->name, $data)) { $key = $column->name; $value = $data[$key]; if (is_null($value)) { $update[] = "{$key} = NULL"; // previously NULLs were not updated } else { if (is_bool($value)) { $value = (int) $value; $update[] = "{$key} = {$value}"; // lets keep pg happy, '' is not correct smallint MDL-13038 } else { $update[] = "{$key} = '{$value}'"; // All incoming data is already quoted } } } } /// Only if we have fields to be updated (this will prevent both wrong updates + /// updates of only LOBs in Oracle if ($update) { $query = "UPDATE {$CFG->prefix}{$table} SET " . implode(',', $update) . " WHERE id = {$dataobject->id}"; if (!($rs = $db->Execute($query))) { debugging($db->ErrorMsg() . '<br /><br />' . s($query)); if (!empty($CFG->dblogerror)) { $debug = array_shift(debug_backtrace()); error_log("SQL " . $db->ErrorMsg() . " in {$debug['file']} on line {$debug['line']}. STATEMENT: {$query}"); } return false; } } /// Under Oracle, MSSQL and PostgreSQL, finally, update all the Clobs and Blobs present in the record /// if we know we have some of them in the query if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') && !empty($dataobject->id) && (!empty($foundclobs) || !empty($foundblobs))) { if (!db_update_lobs($table, $dataobject->id, $foundclobs, $foundblobs)) { return false; //Some error happened while updating LOBs } } return true; }