diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc index dbcbda92e6c3a214b54342f24ee2753d76a7c1b7..91fb159ed1f1a7813f31ea89f9fa236a0c123f69 100644 --- a/modules/field/field.crud.inc +++ b/modules/field/field.crud.inc @@ -339,6 +339,10 @@ function field_read_fields($params = array(), $include_additional = array()) { unset($field['data']); $field += $data; + // Make sure all settings expected in the current execution context are + // present. + $field['settings'] += field_info_field_settings($field['type']); + module_invoke_all('field_read_field', $field); // Populate storage information. @@ -620,7 +624,7 @@ function field_read_instances($params = array(), $include_additional = array()) $query = db_select('field_config_instance', 'fci', array('fetch' => PDO::FETCH_ASSOC)); $query->join('field_config', 'fc', 'fc.id = fci.field_id'); $query->fields('fci'); - #$query->fields('fc', array('type')); + $query->fields('fc', array('type')); // Turn the conditions into a query. foreach ($params as $key => $value) { @@ -650,8 +654,13 @@ function field_read_instances($params = array(), $include_additional = array()) $instance['widget']['module'] = $record['widget_module']; $instance['widget']['active'] = $record['widget_active']; - // TODO D7 : Set default widget settings, default instance settings, default display settings. - // (the modules that defined them might have changed since the instance was last saved). + // Make sure all settings expected in the current execution context are + // present. + $instance['settings'] += field_info_instance_settings($record['type']); + $instance['widget']['settings'] += field_info_widget_settings($instance['widget']['type']); + foreach ($instance['display'] as $build_mode => $display) { + $instance['display'][$build_mode]['settings'] += field_info_formatter_settings($display['type']); + } module_invoke_all('field_read_instance', $instance); $instances[] = $instance; diff --git a/modules/field/field.test b/modules/field/field.test index 629709d87975ba4386e413882eb19c1420d29ac7..f71b24c9fb511ca0eea0e9dc1077fd5984390186 100644 --- a/modules/field/field.test +++ b/modules/field/field.test @@ -1221,6 +1221,7 @@ class FieldCrudTestCase extends DrupalWebTestCase { // - a full fledged $field structure, check that all the values are there // - a minimal $field structure, check all default values are set // defer actual $field comparison to a helper function, used for the two cases above + /** * Test the creation of a field. */ @@ -1255,19 +1256,22 @@ class FieldCrudTestCase extends DrupalWebTestCase { $field_definition = field_create_field($field_definition); $mem = field_test_memorize(); $this->assertIdentical($mem['field_test_field_create_field'][0][0], $field_definition, 'hook_field_create_field() called with correct arguments.'); - $field = field_read_field($field_definition['field_name']); + + // Read the raw record from the {field_config_instance} table. + $result = db_query('SELECT * FROM {field_config} WHERE field_name = :field_name', array(':field_name' => $field_definition['field_name'])); + $record = $result->fetchAssoc(); + $record['data'] = unserialize($record['data']); // Ensure that basic properties are preserved. - $this->assertEqual($field['field_name'], $field_definition['field_name'], t('The field name is properly saved.')); - $this->assertEqual($field['type'], $field_definition['type'], t('The field type is properly saved.')); + $this->assertEqual($record['field_name'], $field_definition['field_name'], t('The field name is properly saved.')); + $this->assertEqual($record['type'], $field_definition['type'], t('The field type is properly saved.')); // Ensure that cardinality defaults to 1. - $this->assertEqual($field['cardinality'], 1, t('Cardinality defaults to 1.')); + $this->assertEqual($record['cardinality'], 1, t('Cardinality defaults to 1.')); // Ensure that default settings are present. - $info = field_info_field_types($field['type']); - $settings = $info['settings']; - $this->assertIdentical($settings, $field['settings'] , t('Default field settings have been written.')); + $field_type = field_info_field_types($field_definition['type']); + $this->assertIdentical($record['data']['settings'], $field_type['settings'], t('Default field settings have been written.')); // Guarantee that the name is unique. try { @@ -1293,6 +1297,35 @@ class FieldCrudTestCase extends DrupalWebTestCase { // TODO : other failures } + /** + * Test reading back a field definition. + */ + function testReadField() { + $field_definition = array( + 'field_name' => 'field_1', + 'type' => 'test_field', + ); + field_create_field($field_definition); + + // Simulate a stored field definition missing a field setting (e.g. a + // third-party module adding a new field setting has been enabled, and + // existing fields do not know the setting yet). + $data = db_result(db_query('SELECT data FROM {field_config} WHERE field_name = :field_name', array(':field_name' => $field_definition['field_name']))); + $data = unserialize($data); + $data['settings'] = array(); + db_update('field_config') + ->fields(array('data' => serialize($data))) + ->condition('field_name', $field_definition['field_name']) + ->execute(); + + // Read the field back. + $field = field_read_field($field_definition['field_name']); + + // Check that all expected settings are in place. + $field_type = field_info_field_types($field_definition['type']); + $this->assertIdentical($field['settings'], $field_type['settings'], t('All expected default field settings are present.')); + } + /** * Test creation of indexes on data column. */ @@ -1336,10 +1369,6 @@ class FieldCrudTestCase extends DrupalWebTestCase { $this->assertEqual($field['indexes'], $expected_indexes, t('Field definition indexes are merged with field type indexes')); } - function testReadField() { - - } - /** * Test the deletion of a field. */ @@ -1450,30 +1479,35 @@ class FieldInstanceCrudTestCase extends DrupalWebTestCase { // - a minimal $instance structure, check all default values are set // defer actual $instance comparison to a helper function, used for the two cases above, // and for testUpdateFieldInstance + + /** + * Test the creation of a field instance. + */ function testCreateFieldInstance() { field_create_instance($this->instance_definition); - $instance = field_read_instance($this->instance_definition['field_name'], $this->instance_definition['bundle']); + + // Read the raw record from the {field_config_instance} table. + $result = db_query('SELECT * FROM {field_config_instance} WHERE field_name = :field_name AND bundle = :bundle', array(':field_name' => $this->instance_definition['field_name'], ':bundle' => $this->instance_definition['bundle'])); + $record = $result->fetchAssoc(); + $record['data'] = unserialize($record['data']); + + //$instance = field_read_instance($this->instance_definition['field_name'], $this->instance_definition['bundle']); $field_type = field_info_field_types($this->field['type']); - $widget_type = field_info_widget_types($instance['widget']['type']); - $formatter_type = field_info_formatter_types($instance['display']['full']['type']); + $widget_type = field_info_widget_types($field_type['default_widget']); + $formatter_type = field_info_formatter_types($field_type['default_formatter']); // Check that default values are set. - $this->assertIdentical($instance['required'], FALSE, t('Required defaults to false.')); - $this->assertIdentical($instance['label'], $this->instance_definition['field_name'], t('Label defaults to field name.')); - $this->assertIdentical($instance['description'], '', t('Description defaults to empty string.')); - - // Check that default instance settings are set. - $this->assertIdentical($instance['settings'], $field_type['instance_settings'] , t('Default instance settings have been written.')); - // Check that the widget is the default one. - $this->assertIdentical($instance['widget']['type'], $field_type['default_widget'], t('Default widget has been written.')); - // Check that default widget settings are set. - $this->assertIdentical($instance['widget']['settings'], $widget_type['settings'] , t('Default widget settings have been written.')); - // Check that we have display info for 'full' build_mode. - $this->assertTrue(isset($instance['display']['full']), t('Display for "full" build_mode has been written.')); - // Check that the formatter is the default one. - $this->assertIdentical($instance['display']['full']['type'], $field_type['default_formatter'], t('Default formatter for "full" build_mode has been written.')); - // Check that the default formatter settings are set. - $this->assertIdentical($instance['display']['full']['settings'], $formatter_type['settings'], t('Default formatter settings for "full" build_mode have been written.')); + $this->assertIdentical($record['data']['required'], FALSE, t('Required defaults to false.')); + $this->assertIdentical($record['data']['label'], $this->instance_definition['field_name'], t('Label defaults to field name.')); + $this->assertIdentical($record['data']['description'], '', t('Description defaults to empty string.')); + $this->assertIdentical($record['widget_type'], $field_type['default_widget'], t('Default widget has been written.')); + $this->assertTrue(isset($record['data']['display']['full']), t('Display for "full" build_mode has been written.')); + $this->assertIdentical($record['data']['display']['full']['type'], $field_type['default_formatter'], t('Default formatter for "full" build_mode has been written.')); + + // Check that default settings are set. + $this->assertIdentical($record['data']['settings'], $field_type['instance_settings'] , t('Default instance settings have been written.')); + $this->assertIdentical($record['data']['widget']['settings'], $widget_type['settings'] , t('Default widget settings have been written.')); + $this->assertIdentical($record['data']['display']['full']['settings'], $formatter_type['settings'], t('Default formatter settings for "full" build_mode have been written.')); // Guarantee that the field/bundle combination is unique. try { @@ -1497,10 +1531,41 @@ class FieldInstanceCrudTestCase extends DrupalWebTestCase { // TODO: test other failures. } + /** + * Test reading back an instance definition. + */ function testReadFieldInstance() { + field_create_instance($this->instance_definition); + + // Simulate a stored instance definition missing various settings (e.g. a + // third-party module adding instance, widget or display settings has been + // enabled, but existing instances do not know the new settings). + $data = db_result(db_query('SELECT data FROM {field_config_instance} WHERE field_name = :field_name AND bundle = :bundle', array(':field_name' => $this->instance_definition['field_name'], ':bundle' => $this->instance_definition['bundle']))); + $data = unserialize($data); + $data['settings'] = array(); + $data['widget']['settings'] = array(); + $data['display']['full']['settings'] = array(); + db_update('field_config_instance') + ->fields(array('data' => serialize($data))) + ->condition('field_name', $this->instance_definition['field_name']) + ->condition('bundle', $this->instance_definition['bundle']) + ->execute(); + + // Read the instance back. + $instance = field_read_instance($this->instance_definition['field_name'], $this->instance_definition['bundle']); + // Check that all expected settings are in place. + $field_type = field_info_field_types($this->field['type']); + $widget_type = field_info_widget_types($instance['widget']['type']); + $formatter_type = field_info_formatter_types($instance['display']['full']['type']); + $this->assertIdentical($instance['settings'], $field_type['instance_settings'] , t('All expected instance settings are present.')); + $this->assertIdentical($instance['widget']['settings'], $widget_type['settings'] , t('All expected widget settings are present.')); + $this->assertIdentical($instance['display']['full']['settings'], $formatter_type['settings'] , t('All expected formatter settings are present.')); } + /** + * Test the update of a field instance. + */ function testUpdateFieldInstance() { field_create_instance($this->instance_definition); $field_type = field_info_field_types($this->field['type']); @@ -1554,6 +1619,9 @@ class FieldInstanceCrudTestCase extends DrupalWebTestCase { // TODO: test failures. } + /** + * Test the deletion of a field instance. + */ function testDeleteFieldInstance() { // TODO: Test deletion of the data stored in the field also. // Need to check that data for a 'deleted' field / instance doesn't get loaded