Beispiel #1
0
/**
 * 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;
}