diff --git a/serial.inc b/serial.inc index cb3dec2..cb28997 100644 --- a/serial.inc +++ b/serial.inc @@ -41,31 +41,33 @@ function _serial_drop_table($field, $instance) { } /** - * Renames serial table(s) when a content type us renamed. + * Renames serial table(s) when a entity bundle us renamed. * - * @param $old_type - * an old node type machine name - * @param $new_type - * a new node type machine name + * @param $bundle_old + * an old entity bundle machine name + * @param $bundle_new + * a new entity bundle machine name */ -function _serial_rename_tables($old_type, $new_type) { +function _serial_rename_tables($entity_type, $bundle_old, $bundle_new) { // Build the query to find all affected tables. - $query = db_select('field_config', 'f')->fields('f', array('field_name')); + $query = db_select('field_config', 'f') + ->fields('f', array('field_name')); $table_joined_alias = $query->join( 'field_config_instance', 'i', - '(f.field_name = i.field_name) AND ' . - '(f.type = :field_type) AND (i.bundle = :bundle_type)', - array(':field_type' => 'serial', ':bundle_type' => $new_type) - ); + '(f.field_name = i.field_name)' + ); + $query->condition('f.type', 'serial'); + $query->condition('i.entity_type', $entity_type); + $query->condition('i.bundle', $bundle_new); // Add an access check and execute it. $result = $query->addTag('node_access')->execute(); // Rename each affected table. foreach ($result as $record) { - $old_table = _serial_get_table_name($old_type, $record->field_name); - $new_table = _serial_get_table_name($new_type, $record->field_name); + $old_table = _serial_get_table_name($entity_type, $bundle_old, $record->field_name); + $new_table = _serial_get_table_name($entity_type, $bundle_new, $record->field_name); db_rename_table($old_table, $new_table); } } @@ -81,22 +83,24 @@ function _serial_rename_tables($old_type, $new_type) { * the name of the assistant table of the specified field instance. */ function _serial_get_field_table_name($field, $instance) { - return _serial_get_table_name($instance['bundle'], $field['field_name']); + return _serial_get_table_name($instance['entity_type'], $instance['bundle'], $field['field_name']); } /** * Gets the name of the assistant table for a specific field. * + * @param $entity_type + * type of entity (e.g. node) * @param $bundle - * the name of the entity type that contains the field + * the name of the entity type that contains the field (e.g. content type) * @param $field_name * the name of the field * @return * the name of the assistant table of the specified field. */ -function _serial_get_table_name($bundle, $field_name) { +function _serial_get_table_name($entity_type, $bundle, $field_name) { return db_escape_table( // be on the safe side - 'serial_' . $bundle . '_' . $field_name); + 'serial_' . $entity_type . '_' . $bundle . '_' . $field_name); } /** @@ -129,10 +133,10 @@ function _serial_get_table_schema() { } /** - * Generates a unique serial value (unique per node type). + * Generates a unique serial value (unique per entity bundle). * - * @param $nid - * id of the node for which to generate a serial value + * @param $entity_type + * type of entity (e.g. node) * @param $bundle * a containing bundle (e.g. content type) * @param $field_name @@ -142,10 +146,10 @@ function _serial_get_table_schema() { * @return * the unique serial value number. */ -function _serial_generate_value($bundle, $field_name, $delete = TRUE) { +function _serial_generate_value($entity_type, $bundle, $field_name, $delete = TRUE) { // Get the name of the relevant table. - $table = _serial_get_table_name($bundle, $field_name); + $table = _serial_get_table_name($entity_type, $bundle, $field_name); // Insert a temporary record to get a new unique serial value. $uniqid = uniqid('', TRUE); @@ -170,48 +174,67 @@ function _serial_generate_value($bundle, $field_name, $delete = TRUE) { } /** - * Initializes the value of a new serial field in existing nodes. + * Initializes the value of a new serial field in existing entities. * + * @param $entity_type + * type of entity (e.g. node) * @param $bundle * a containing bundle (e.g. content type) * @param $field_name * the field name * @return - * the number of existing nodes that have been initialized. + * the number of existing entities that have been initialized. */ -function _serial_init_old_nodes($bundle, $field_name) { - // Retrieve all the node ids of that type: - $query = "SELECT nid FROM {node} WHERE type = :type ORDER BY nid"; - // TODO: Currently works only for nodes - should support comments and users. - $result = db_query($query, array('type' => $bundle)); +function _serial_init_old_entities($entity_type, $bundle, $field_name) { + // Prepare meta data. + $entity_info = entity_get_info($entity_type); + $base_table = $entity_info['base table']; + $bundle_key = $entity_info['entity keys']['bundle']; + $id_key = $entity_info['entity keys']['id']; + + // @todo - What if $base_table or $id_key is empty? + + // Build the query. + $query = "SELECT $id_key FROM {$base_table} "; + if (!empty($bundle_key)) { + // Some entity types (e.g. user) do not have bundle. + $query .= "WHERE $bundle_key = :type "; + } + $query .= "ORDER BY $id_key"; - // Allocate a serial number for every old node: + // Execute the query. + // @todo - Which is better: EntityFieldQuery or db_query? + $results = db_query($query, array('type' => $bundle)); + + // Allocate a serial number for every old entity: $count = 0; - foreach ($result as $node) { - $nid = $node->nid; - $node = node_load($nid); - $sid = _serial_generate_value($bundle, $field_name, FALSE); - $node->{$field_name} = array('und' => array(array('value' => $sid))); - node_save($node); - $count++; + foreach ($results as $result) { + $id = $result->{$id_key}; + if ($id > 0) { + // Check for valid id. Prevent anonymous user from being updated. + $entity = entity_load_single($entity_type, $id); + $sid = _serial_generate_value($entity_type, $bundle, $field_name, FALSE); + $entity->{$field_name} = array('und' => array(array('value' => $sid))); + entity_save($entity_type, $entity); + $count++; + } } - // Return the number of existing nodes that have been initialized: + // Return the number of existing entities that have been initialized: return $count; } /** * Retrieves all the managed serial fields. * - * @return result set containing pairs of (node type name, field name). + * @return result set containing of (entity type, entity bundle, field name). */ function _serial_get_all_fields() { $query = db_select('field_config', 'f'); $query->join('field_config_instance', 'i', 'i.field_name = f.field_name'); - $query->fields('i', array('bundle', 'field_name')) + $query->fields('i', array('entity_type', 'bundle', 'field_name')) ->condition('f.type', 'serial', '=') ->condition('i.deleted', 0, '='); $result = $query->execute(); return $result->fetchAll(); } - diff --git a/serial.info b/serial.info index 56dfddd..322b7db 100644 --- a/serial.info +++ b/serial.info @@ -2,6 +2,7 @@ name = Serial description = Defines atomic auto increment (serial) field type. package = Fields core = 7.x +dependencies[] = entity dependencies[] = field files[] = serial.module diff --git a/serial.install b/serial.install index 18e72bf..019eb00 100644 --- a/serial.install +++ b/serial.install @@ -48,7 +48,7 @@ function serial_schema() { $schema = array(); $result = _serial_get_all_fields(); foreach ($result as $field) { - $table = _serial_get_table_name($field->bundle, $field->field_name); + $table = _serial_get_table_name($field->entity_type, $field->bundle, $field->field_name); $schema[$table] = $table_schema; } @@ -71,7 +71,7 @@ function serial_update_7130() { $result = _serial_get_all_fields(); foreach ($result as $field) { // Empty the table. - $table = _serial_get_table_name($field->bundle, $field->field_name); + $table = _serial_get_table_name($field->entity_type, $field->bundle, $field->field_name); db_delete($table)->execute(); // Drop nid field and key @@ -84,3 +84,15 @@ function serial_update_7130() { } } +/** + * Add 'node_' to all serial tables. + * + * Change from serial_{content type}_{field name} to serial_node_{content type}_{field name} + */ +function serial_update_7131() { + // All old serial tables are of 'node' entity type. + foreach (db_find_tables('serial_%') as $tablename) { + $tablename_without_serial = preg_replace('/^serial_/', '', $tablename); + db_rename_table($tablename, 'serial_node_' . $tablename_without_serial); + } +} diff --git a/serial.module b/serial.module index 688bb10..e79427d 100644 --- a/serial.module +++ b/serial.module @@ -34,10 +34,10 @@ function serial_field_create_instance($instance) { _serial_create_table($field, $instance); // Set serial values for old objects - $old_count = _serial_init_old_nodes($instance['bundle'], $field['field_name']); + $old_count = _serial_init_old_entities($instance['entity_type'], $instance['bundle'], $field['field_name']); if ($old_count) { drupal_set_message( - t('Serial values have been automatically set for %count existing nodes.', + t('Serial values have been automatically set for %count existing entities.', array('%count' => $old_count)) ); } @@ -68,10 +68,6 @@ function serial_form_alter(&$form, $form_state, $form_id) { t('Serial field %field has been created.', array('%field' => $field_name)) ); - - // Go back to Managed Fields: - $type = $form['#bundle']; - drupal_goto("admin/structure/types/manage/$type/fields"); } } @@ -81,7 +77,7 @@ function serial_form_alter(&$form, $form_state, $form_id) { function serial_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) { module_load_include('inc', 'serial'); if (empty($items)) { - $sid = _serial_generate_value($instance['bundle'], $field['field_name']); + $sid = _serial_generate_value($entity_type, $instance['bundle'], $field['field_name']); $items = array(array('value' => $sid)); } } @@ -106,13 +102,13 @@ function serial_node_presave($node) { } /** - * Implements hook_node_type_update(). + * Implements hook_field_attach_rename_bundle(). */ -function serial_node_type_update($info) { - // Handle content type rename: - if (isset($info->old_type) && ($info->old_type != $info->type)) { +function serial_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) { + // Update the extra weights variable with new information. + if ($bundle_old !== $bundle_new) { module_load_include('inc', 'serial'); - _serial_rename_tables($info->old_type, $info->type); + _serial_rename_tables($entity_type, $bundle_old, $bundle_new); } } @@ -231,4 +227,3 @@ function serial_field_widget(&$form, &$form_state, $field, $instance, $items, $d ) ); } -