diff -u b/serial.inc b/serial.inc --- b/serial.inc +++ b/serial.inc @@ -43,21 +43,20 @@ /** * Renames serial table(s) when a entity bundle us renamed. * - * @param $bundle_old - * An old entity bundle machine name - * @param $bundle_new - * A new entity bundle machine name + * @param string $entity_type + * Type of entity. + * @param string $bundle_old + * An old entity bundle machine name. + * @param string $bundle_new + * A new entity bundle machine name. */ 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->join( - 'field_config_instance', - 'i', - "(f.field_name = i.field_name)" - ); + $query->join('field_config_instance', 'i', '(f.field_name = i.field_name)'); + $query->condition('f.type', 'serial'); $query->condition('i.entity_type', $entity_type); $query->condition('i.bundle', $bundle_new); @@ -89,7 +88,7 @@ /** * Gets the name of the assistant table for a specific field. * - * @param $entity_type + * @param string $entity_type * Type of entity (e.g. node) * @param string $bundle * The name of the entity type that contains the field (e.g. content type) @@ -100,7 +99,7 @@ * The name of the assistant table of the specified field. */ function _serial_get_table_name($entity_type, $bundle, $field_name) { - return db_escape_table('serial_' . $entity_type . '_' . $bundle . '_' . $field_name); + return db_escape_table("serial_{$entity_type}_{$bundle}_{$field_name}"); } /** @@ -114,16 +113,17 @@ 'fields' => array( 'sid' => array( 'type' => 'serial', - 'unsigned' => TRUE, 'not null' => TRUE, + 'unsigned' => TRUE, 'description' => 'The atomic serial field.', ), 'uniqid' => array( - 'description' => 'Unique temporary allocation Id.', 'type' => 'varchar', 'length' => 23, + 'default' => '', 'not null' => TRUE, - 'default' => ''), + 'description' => 'Unique temporary allocation Id.', + ), ), 'primary key' => array('sid'), 'unique keys' => array( @@ -135,7 +135,7 @@ /** * Generates a unique serial value (unique per entity bundle). * - * @param $entity_type + * @param string $entity_type * Type of entity (e.g. node) * @param string $bundle * Containing bundle (e.g. content type). @@ -150,7 +150,6 @@ function _serial_generate_value($entity_type, $bundle, $field_name, $delete = TRUE) { // Get the name of the relevant table. $table = _serial_get_table_name($entity_type, $bundle, $field_name); - // Insert a temporary record to get a new unique serial value. $uniqid = uniqid('', TRUE); $sid = db_insert($table) @@ -174,9 +173,7 @@ /** * Initializes the value of a new serial field in existing entities. * - * @todo Currently works only for nodes - should support comments and users. - * - * @param $entity_type + * @param string $entity_type * Type of entity (e.g. node) * @param string $bundle * Containing bundle (e.g. content type). @@ -187,33 +184,23 @@ * Number of existing entities that have been initialized. */ 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 = new EntityFieldQuery(); + $query->entityCondition('entity_type', $entity_type) + ->fieldCondition($field_name); + + // The "comment" entity type does not support bundle conditions. + // @see https://api.drupal.org/api/drupal/includes!entity.inc/function/EntityFieldQuery%3A%3AentityCondition/7 + if ('comment' !== $entity_type) { + $query->entityCondition('bundle', $bundle); } - $query .= "ORDER BY $id_key"; - // 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 ($results as $result) { - $id = $result->{$id_key}; - if ($id > 0) { - // Check for valid id. Prevent anonymous user from being updated. - $entity = entity_load($entity_type, array($id)); + $results = $query->execute(); + + if (!empty($results[$entity_type])) { + $entity_info = entity_get_info($entity_type); + + foreach ($results[$entity_type] as $entity) { + $entity = entity_load_unchanged($entity_type, $entity->{$entity_info['entity keys']['id']}); $entity->{$field_name} = array( LANGUAGE_NONE => array( array( @@ -221,26 +208,28 @@ ), ), ); - entity_save($entity_type, $entity); - $count++; + + field_attach_insert($entity_type, $entity); } + + return count($results[$entity_type]); } - // Return the number of existing entities that have been initialized. - return $count; + return 0; } /** * Retrieves all the managed serial fields. * - * @return array + * @return string[] * Result set containing 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'); - return $query->fields('i', array('entity_type', 'bundle', 'field_name')) + return $query + ->fields('i', array('entity_type', 'bundle', 'field_name')) ->condition('f.type', 'serial') ->condition('i.deleted', 0) ->execute() diff -u b/serial.install b/serial.install --- b/serial.install +++ b/serial.install @@ -72,13 +72,14 @@ /** - * Add 'node_' to all serial tables. + * Add 'node_' to all existing serial tables. * - * Change from serial_{content type}_{field name} to serial_node_{content type}_{field name} + * Change name: + * 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_add_node = preg_replace('/^serial_/', 'serial_node_', $tablename); - db_rename_table($tablename, $tablename_add_node); + foreach (db_find_tables('serial_%') as $table) { + db_rename_table($table, preg_replace('/^serial_/', 'serial_node_', $table)); } } diff -u b/serial.module b/serial.module --- b/serial.module +++ b/serial.module @@ -24,7 +24,7 @@ /** * Implements hook_field_create_instance(). */ -function serial_field_create_instance($instance) { +function serial_field_create_instance(array $instance) { $field = field_read_field($instance['field_name']); if ('serial' == $field['type']) { @@ -46,7 +46,7 @@ /** * Implements hook_field_delete_instance(). */ -function serial_field_delete_instance($instance) { +function serial_field_delete_instance(array $instance) { $field = field_read_field($instance['field_name']); if ('serial' == $field['type']) { @@ -59,7 +59,7 @@ /** * Implements hook_form_alter(). */ -function serial_form_alter(&$form, $form_state, $form_id) { +function serial_form_alter(array &$form, array &$form_state, $form_id) { if ('field_ui_field_settings_form' == $form_id && 'serial' == $form['field']['type']['#value']) { drupal_set_message(t('Serial field %field has been created.', array( '%field' => $form['field']['field_name']['#value'], @@ -72,11 +72,15 @@ /** * Implements hook_field_presave(). */ -function serial_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) { +function serial_field_presave($entity_type, $entity, array $field, array $instance, $langcode, array &$items) { if (empty($items)) { module_load_include('inc', 'serial'); - $items = array(array('value' => _serial_generate_value($entity_type, $instance['bundle'], $field['field_name']))); + $items = array( + array( + 'value' => _serial_generate_value($entity_type, $instance['bundle'], $field['field_name']), + ), + ); } } @@ -124,7 +128,7 @@ /** * Implements hook_field_formatter_view(). */ -function serial_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { +function serial_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, array $items, $display) { $element = array(); // Define the field contents for the single default formatter. @@ -156,7 +160,7 @@ /** * Theme function for the default formatter. */ -function theme_serial_formatter_default($variables) { +function theme_serial_formatter_default(array $variables) { return $variables['serial_id']; } @@ -175,7 +179,7 @@ /** * Implements hook_field_widget(). */ -function serial_field_widget(&$form, &$form_state, $field, $instance, $items, $delta = 0) { +function serial_field_widget(array &$form, array &$form_state, array $field, array $instance, array $items, $delta = 0) { return array( 'value' => array( '#type' => 'hidden', @@ -189,50 +193,42 @@ * * Replace token for generic entity type. */ -function serial_tokens($type, $tokens, $data, $options) { +function serial_tokens($type, array $tokens, array $data = array(), array $options = array()) { $replacements = array(); - $sanitize = !empty($options['sanitize']); - $entity_info = entity_get_info($type); - // Make sure type is entity type. - if (empty($entity_info)) { + + if (empty($entity_info) || empty($data[$type])) { return $replacements; } - $entity_type = $type; - if (!empty($data[$entity_type])) { - // Generic entity. - $entity = $data[$entity_type]; - foreach ($tokens as $name => $original) { - // Convert token to field name. - $field_name = str_replace('-', '_', $name); - $field_info = field_info_field($field_name); - if ($field_info['type'] == 'serial') { - // Check if field is used in a pathauto pattern. If so, skip token replacement. - $pathauto_match = FALSE; - if (module_exists('pathauto')) { - $pattern = pathauto_pattern_load_by_entity($entity_type, $data[$entity_type]->type); - $path_items = explode('/', $pattern); - foreach ($path_items as $path_item) { - if (preg_match('/^\[(.*):field_(.*)\]$/', $path_item, $matches)) { - if ($field_name == 'field_' . $matches[2]) { - $pathauto_match = TRUE; - break; - } - } - } - } - if (!$pathauto_match) { - $items = field_get_items($entity_type, $entity, $field_name); - if (empty($items)) { - continue; - } - $item = reset($items); - $serial_value = $item['value']; - $replacements[$original] = $sanitize ? filter_xss($serial_value) : $serial_value; - } + $entity = $data[$type]; + $pathauto = module_exists('pathauto'); + + foreach ($tokens as $name => $original) { + // Convert token to field name. + $field_name = str_replace('-', '_', $name); + $field_info = field_info_field($field_name); + + if ('serial' === $field_info['type']) { + continue; + } + + if ($pathauto) { + $pattern = pathauto_pattern_load_by_entity($type, $entity->{$entity_info['bundle keys']['bundle']}); + + if (strpos($pattern, "$type:$field_name") !== FALSE) { + continue; } } + + /* @var array $items */ + $items = field_get_items($type, $entity, $field_name); + + if (FALSE !== $items) { + continue; + } + + $replacements[$original] = $items[0]['value']; } return $replacements; only in patch2: unchanged: --- a/serial.info +++ b/serial.info @@ -2,6 +2,5 @@ name = Serial description = Defines atomic auto increment (serial) field type. package = Fields core = 7.x -dependencies[] = field -files[] = serial.module +dependencies[] = field