? files ? mw.patch ? phpinfo.php ? tmp.patch ? sites/all/modules ? sites/all/themes ? sites/default/mw.patch ? sites/default/tmp.patch Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.689 diff -u -F^f -r1.689 common.inc --- includes/common.inc 27 Sep 2007 17:11:07 -0000 1.689 +++ includes/common.inc 27 Sep 2007 21:45:15 -0000 @@ -2988,6 +2988,147 @@ function _drupal_initialize_schema($modu } /** + * Retrieve a list of fields from a table schema. The list is suitable for use in a SQL query. + * + * @param $table + * The name of the table from which to retrieve fields. + * @param + * An optional prefix to to all fields. + * + * @return An array of fields. + **/ +function drupal_schema_fields_sql($table, $prefix = NULL) { + $schema = drupal_get_schema($table); + $fields = array_keys($schema['fields']); + if ($prefix) { + $columns = array(); + foreach ($fields as $field) { + $columns[] = "$prefix.$field"; + } + return $columns; + } + else { + return $fields; + } +} + +/** + * Save a record to the database based upon the schema. Default values are + * filled in for missing items, and 'serial' (auto increment) types are + * filled in with IDs. + * + * @param $table + * The name of the table; this must exist in schema API. + * @param $object + * The object to write. This is a reference, as defaults according to + * the schema may be filled in on the object, as well as ID on the serial + * type(s). Both array an object types may be passed. + * @param update + * If this is an update, specify the primary keys' field names. It is the + * caller's responsibility to know if a record for this object already + * exists in the database. If there is only 1 key, you may pass a simple string. + * @return (boolean) Failure to write a record will return FALSE. Otherwise, + * TRUE is returned. The $object parameter contains values for any serial + * fields defined by the $table. For example, $object->nid will be populated + * after inserting a new node. + */ +function drupal_write_record($table, &$object, $update = array()) { + // Standardize $update to an array. + if (is_string($update)) { + $update = array($update); + } + + // Convert to an object if needed. + if (is_array($object)) { + $object = (object) $object; + $array = TRUE; + } + else { + $array = FALSE; + } + + $schema = drupal_get_schema($table); + if (empty($schema)) { + return FALSE; + } + + $fields = $defs = $values = $serials = array(); + + // Go through our schema, build SQL, and when inserting, fill in defaults for + // fields that are not set. + foreach ($schema['fields'] as $field => $info) { + // Special case -- skip serial types if we are updating. + if ($info['type'] == 'serial' && count($update)) { + continue; + } + + // For inserts, populate defaults from Schema if not already provided + if (!isset($object->$field) && !count($update) && isset($info['default'])) { + $object->$field = $info['default']; + } + + // Track serial fields so we can helpfully populate them after the query. + if ($info['type'] == 'serial') { + $serials[] = $field; + // Ignore values for serials when inserting data. Unsupported. + $object->$field = 'NULL'; + } + + // Build arrays for the fields, placeholders, and values in our query. + if (isset($object->$field)) { + $fields[] = $field; + $placeholders[] = db_type_placeholder($info['type']); + + if (empty($info['serialize'])) { + $values[] = $object->$field; + } + else { + $values[] = serialize($object->$field); + } + } + } + + // Build the SQL. + $query = ''; + if (!count($update)) { + $query = "INSERT INTO {$table} (" . implode(', ', $fields) . ') VALUES (' . implode(', ', $placeholders) . ')'; + $return = SAVED_NEW; + } + else { + $query = ''; + foreach ($fields as $id => $field) { + if ($query) { + $query .= ', '; + } + $query .= $field . ' = ' . $placeholders[$id]; + } + + foreach ($update as $key){ + $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']); + $values[] = $object->$key; + } + + $query = "UPDATE {$table} SET $query WHERE ". implode(' AND ', $conditions); + $return = SAVED_UPDATED; + } + db_query($query, $values); + + if ($serials) { + // Get last insert ids and fill them in. + foreach ($serials as $field) { + $object->$field = db_last_insert_id($table, $field); + } + } + + // If we began with an array, convert back so we don't surprise the caller. + if ($array) { + $object = (array)$object; + } + + return $return; +} + +/** * @} End of "ingroup schemaapi". */ Index: includes/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.inc,v retrieving revision 1.81 diff -u -F^f -r1.81 database.inc --- includes/database.inc 27 Sep 2007 16:52:00 -0000 1.81 +++ includes/database.inc 27 Sep 2007 21:45:16 -0000 @@ -199,7 +199,7 @@ function _db_query_callback($match, $ini * The Schema API type of a field (e.g. 'int', 'text', or 'varchar'). */ function db_placeholders($arguments, $type = 'int') { - $placeholder = _db_type_placeholder($type); + $placeholder = db_type_placeholder($type); return implode(',', array_fill(0, count($arguments), $placeholder)); } @@ -487,7 +487,7 @@ function db_field_names($fields) { * @return * The placeholder string to embed in a query for that type. */ -function _db_type_placeholder($type) { +function db_type_placeholder($type) { switch ($type) { case 'varchar': case 'text': @@ -516,7 +516,7 @@ function _db_type_placeholder($type) { // There is no safe value to return here, so return something that // will cause the query to fail. - return 'unsupported type '. $type .'for _db_type_placeholder'; + return 'unsupported type '. $type .'for db_type_placeholder'; } /** Index: includes/database.mysql-common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.mysql-common.inc,v retrieving revision 1.12 diff -u -F^f -r1.12 database.mysql-common.inc --- includes/database.mysql-common.inc 14 Sep 2007 17:46:32 -0000 1.12 +++ includes/database.mysql-common.inc 27 Sep 2007 21:45:16 -0000 @@ -297,7 +297,7 @@ function db_add_field(&$ret, $table, $fi $ret[] = update_sql($query); if (isset($spec['initial'])) { // All this because update_sql does not support %-placeholders. - $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. _db_type_placeholder($spec['type']); + $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. db_type_placeholder($spec['type']); $result = db_query($sql, $spec['initial']); $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql .' ('. $spec['initial'] .')')); } Index: includes/database.pgsql.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.pgsql.inc,v retrieving revision 1.61 diff -u -F^f -r1.61 database.pgsql.inc --- includes/database.pgsql.inc 25 Sep 2007 11:44:35 -0000 1.61 +++ includes/database.pgsql.inc 27 Sep 2007 21:45:19 -0000 @@ -700,7 +700,7 @@ function db_add_field(&$ret, $table, $fi $ret[] = update_sql($query); if (isset($spec['initial'])) { // All this because update_sql does not support %-placeholders. - $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. _db_type_placeholder($spec['type']); + $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. db_type_placeholder($spec['type']); $result = db_query($sql, $spec['initial']); $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql .' ('. $spec['initial'] .')')); } Index: includes/file.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/file.inc,v retrieving revision 1.105 diff -u -F^f -r1.105 file.inc --- includes/file.inc 25 Sep 2007 12:39:31 -0000 1.105 +++ includes/file.inc 27 Sep 2007 21:45:22 -0000 @@ -574,8 +574,10 @@ function file_save_upload($source, $vali } // If we made it this far it's safe to record this file in the database. - db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, %d, %d)", $user->uid, $file->filename, $file->filepath, $file->filemime, $file->filesize, FILE_STATUS_TEMPORARY, time()); - $file->fid = db_last_insert_id('files', 'fid'); + $file->uid = $user->uid; + $file->status = FILE_STATUS_TEMPORARY; + $file->timestamp = time(); + drupal_write_record('files', $file); // Add file to the cache. $upload_cache[$source] = $file; Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.888 diff -u -F^f -r1.888 node.module --- modules/node/node.module 27 Sep 2007 12:56:04 -0000 1.888 +++ modules/node/node.module 27 Sep 2007 21:45:26 -0000 @@ -652,14 +652,20 @@ function node_load($param = array(), $re return FALSE; } + // Retrieve a field list based on the site's schema. + $fields = drupal_schema_fields_sql('node', 'n'); + $fields = array_merge($fields, drupal_schema_fields_sql('node_revisions', 'r')); + $fields = array_merge($fields, array('u.name', 'u.data')); + $fields = implode(', ', $fields); + // Retrieve the node. // No db_rewrite_sql is applied so as to get complete indexing for search. if ($revision) { array_unshift($arguments, $revision); - $node = db_fetch_object(db_query('SELECT n.nid, r.vid, n.type, n.status, n.language, n.created, n.changed, n.comment, n.promote, n.sticky, n.tnid, n.translate, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.nid = n.nid AND r.vid = %d WHERE '. $cond, $arguments)); + $node = db_fetch_object(db_query('SELECT '. $fields. ' FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.nid = n.nid AND r.vid = %d WHERE '. $cond, $arguments)); } else { - $node = db_fetch_object(db_query('SELECT n.nid, n.vid, n.type, n.status, n.language, n.created, n.changed, n.comment, n.promote, n.sticky, n.tnid, n.translate, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond, $arguments)); + $node = db_fetch_object(db_query('SELECT '. $fields. ' FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond, $arguments)); } if ($node && $node->nid) { @@ -755,7 +761,6 @@ function node_submit($node) { $node->uid = 0; } } - $node->created = !empty($node->date) ? strtotime($node->date) : time(); $node->validated = TRUE; @@ -777,16 +782,13 @@ function node_save(&$node) { // Insert a new node. $node->is_new = TRUE; } + elseif (!empty($node->revision)) { + $node->old_vid = $node->vid; + } else { - // We need to ensure that all node fields are filled. - $node_current = node_load($node->nid); - foreach ($node as $field => $data) { - $node_current->$field = $data; - } - $node = $node_current; - - if (!empty($node->revision)) { - $node->old_vid = $node->vid; + // When updating a node, avoid clobberring an existing log entry with an empty one. + if (empty($node->log)) { + unset($node->log); } } @@ -797,65 +799,24 @@ function node_save(&$node) { // The changed timestamp is always updated for bookkeeping purposes (revisions, searching, ...) $node->changed = time(); - // Split off revisions data to another structure - $revisions_table_values = array('nid' => &$node->nid, - 'title' => $node->title, 'body' => isset($node->body) ? $node->body : '', - 'teaser' => $node->teaser, 'timestamp' => $node->changed, - 'uid' => $user->uid, 'format' => isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT); - $revisions_table_types = array('nid' => '%d', - 'title' => "'%s'", 'body' => "'%s'", - 'teaser' => "'%s'", 'timestamp' => '%d', - 'uid' => '%d', 'format' => '%d'); - if (!empty($node->log) || $node->is_new || (isset($node->revision) && $node->revision)) { - // Only store the log message if there's something to store; this prevents - // existing log messages from being unintentionally overwritten by a blank - // message. A new revision will have an empty log message (or $node->log). - $revisions_table_values['log'] = !empty($node->log) ? $node->log : ''; - $revisions_table_types['log'] = "'%s'"; - } - $node_table_values = array( - 'title' => $node->title, 'type' => $node->type, 'uid' => $node->uid, - 'status' => $node->status, 'language' => $node->language, 'created' => $node->created, - 'changed' => $node->changed, 'comment' => $node->comment, - 'promote' => $node->promote, 'sticky' => $node->sticky); - $node_table_types = array( - 'title' => "'%s'", 'type' => "'%s'", 'uid' => '%d', - 'status' => '%d', 'language' => "'%s'", 'created' => '%d', - 'changed' => '%d', 'comment' => '%d', - 'promote' => '%d', 'sticky' => '%d'); + $node->timestamp = time(); + $node->format = isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT; $update_node = TRUE; + //Generate the node table query and the //the node_revisions table query if ($node->is_new) { - $node_query = 'INSERT INTO {node} ('. implode(', ', array_keys($node_table_types)) .') VALUES ('. implode(', ', $node_table_types) .')'; - db_query($node_query, $node_table_values); - $node->nid = db_last_insert_id('node', 'nid'); - $revisions_query = 'INSERT INTO {node_revisions} ('. implode(', ', array_keys($revisions_table_types)) .') VALUES ('. implode(', ', $revisions_table_types) .')'; - db_query($revisions_query, $revisions_table_values); - $node->vid = db_last_insert_id('node_revisions', 'vid'); + drupal_write_record('node', $node); + drupal_write_record('node_revisions', $node); $op = 'insert'; } else { - $arr = array(); - foreach ($node_table_types as $key => $value) { - $arr[] = $key .' = '. $value; - } - $node_table_values[] = $node->nid; - $node_query = 'UPDATE {node} SET '. implode(', ', $arr) .' WHERE nid = %d'; - db_query($node_query, $node_table_values); + drupal_write_record('node', $node, 'nid'); if (!empty($node->revision)) { - $revisions_query = 'INSERT INTO {node_revisions} ('. implode(', ', array_keys($revisions_table_types)) .') VALUES ('. implode(', ', $revisions_table_types) .')'; - db_query($revisions_query, $revisions_table_values); - $node->vid = db_last_insert_id('node_revisions', 'vid'); + drupal_write_record('node_revisions', $node); } else { - $arr = array(); - foreach ($revisions_table_types as $key => $value) { - $arr[] = $key .' = '. $value; - } - $revisions_table_values[] = $node->vid; - $revisions_query = 'UPDATE {node_revisions} SET '. implode(', ', $arr) .' WHERE vid = %d'; - db_query($revisions_query, $revisions_table_values); + drupal_write_record('node_revisions', $node, 'vid'); $update_node = FALSE; } $op = 'update'; Index: modules/taxonomy/taxonomy.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.admin.inc,v retrieving revision 1.4 diff -u -F^f -r1.4 taxonomy.admin.inc --- modules/taxonomy/taxonomy.admin.inc 19 Sep 2007 19:02:57 -0000 1.4 +++ modules/taxonomy/taxonomy.admin.inc 27 Sep 2007 21:45:26 -0000 @@ -180,7 +180,7 @@ function taxonomy_overview_terms($vocabu if ($vocabulary->tags) { // We are not calling taxonomy_get_tree because that might fail with a big // number of tags in the freetagging vocabulary. - $results = pager_query(db_rewrite_sql('SELECT t.*, h.parent FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE t.vid = %d ORDER BY weight, name', 't', 'tid'), $page_increment, 0, NULL, $vid); + $results = pager_query(db_rewrite_sql('SELECT t.*, h.parent FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE t.vid = %d ORDER BY weight, name', 't', 'tid'), $page_increment, 0, NULL, $vocabulary->vid); while ($term = db_fetch_object($results)) { $rows[] = array( l($term->name, "taxonomy/term/$term->tid"), @@ -207,7 +207,7 @@ function taxonomy_overview_terms($vocabu $GLOBALS['pager_total'][] = intval($total_entries / $page_increment) + 1; // FIXME } - $output .= theme('table', $header, $rows, array('id' => 'taxonomy')); + $output = theme('table', $header, $rows, array('id' => 'taxonomy')); if ($vocabulary->tags || $total_entries >= $page_increment) { $output .= theme('pager', NULL, $page_increment); } Index: modules/taxonomy/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v retrieving revision 1.383 diff -u -F^f -r1.383 taxonomy.module --- modules/taxonomy/taxonomy.module 25 Sep 2007 14:44:50 -0000 1.383 +++ modules/taxonomy/taxonomy.module 27 Sep 2007 21:45:26 -0000 @@ -165,8 +165,12 @@ function taxonomy_menu() { function taxonomy_save_vocabulary(&$edit) { $edit['nodes'] = empty($edit['nodes']) ? array() : $edit['nodes']; + if (!isset($edit['module'])) { + $edit['module'] = 'taxonomy'; + } + if (!empty($edit['vid']) && !empty($edit['name'])) { - db_query("UPDATE {vocabulary} SET name = '%s', description = '%s', help = '%s', multiple = %d, required = %d, hierarchy = %d, relations = %d, tags = %d, weight = %d, module = '%s' WHERE vid = %d", $edit['name'], $edit['description'], $edit['help'], $edit['multiple'], $edit['required'], $edit['hierarchy'], $edit['relations'], $edit['tags'], $edit['weight'], isset($edit['module']) ? $edit['module'] : 'taxonomy', $edit['vid']); + drupal_write_record('vocabulary', $edit, 'vid'); db_query("DELETE FROM {vocabulary_node_types} WHERE vid = %d", $edit['vid']); foreach ($edit['nodes'] as $type => $selected) { db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type); @@ -178,8 +182,7 @@ function taxonomy_save_vocabulary(&$edit $status = taxonomy_del_vocabulary($edit['vid']); } else { - db_query("INSERT INTO {vocabulary} (name, description, help, multiple, required, hierarchy, relations, tags, weight, module) VALUES ('%s', '%s', '%s', %d, %d, %d, %d, %d, %d, '%s')", $edit['name'], isset($edit['description']) ? $edit['description'] : NULL, isset($edit['help']) ? $edit['help'] : NULL, $edit['multiple'], $edit['required'], $edit['hierarchy'], $edit['relations'], isset($edit['tags']) ? $edit['tags'] : NULL, $edit['weight'], isset($edit['module']) ? $edit['module'] : 'taxonomy'); - $edit['vid'] = db_last_insert_id('vocabulary', 'vid'); + drupal_write_record('vocabulary', $edit); foreach ($edit['nodes'] as $type => $selected) { db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type); } @@ -231,7 +234,7 @@ function taxonomy_save_term(&$form_value ); if (!empty($form_values['tid']) && $form_values['name']) { - db_query("UPDATE {term_data} SET name = '%s', description = '%s', weight = %d WHERE tid = %d", $form_values['name'], $form_values['description'], $form_values['weight'], $form_values['tid']); + drupal_write_record('term_data', $form_values, 'tid'); $hook = 'update'; $status = SAVED_UPDATED; } @@ -239,8 +242,7 @@ function taxonomy_save_term(&$form_value return taxonomy_del_term($form_values['tid']); } else { - db_query("INSERT INTO {term_data} (name, description, vid, weight) VALUES ('%s', '%s', %d, %d)", $form_values['name'], $form_values['description'], $form_values['vid'], $form_values['weight']); - $form_values['tid'] = db_last_insert_id('term_data', 'tid'); + drupal_write_record('term_data', $form_values); $hook = 'insert'; $status = SAVED_NEW; }