I've created a custom entity. In the submit function for the form that creates the entity, I've got the following:

function shop_form_submit($form, &$form_state)
{
	global $user;
	$shop = &$form_state['shop'];
	// Set the shop's uid if it's being created at this time.
	if (empty($shop->uid))
	{
		$shop->uid = $user->uid;
	}
	$shop->title = $form_state['values']['title'];
	$shop->revision = $form_state['values']['revision'];
	
	// Save the shop.
	shop_save($shop);

	// Notify the user.
	drupal_set_message(t('Shop saved'));
	
	// Notify field widgets.
	field_attach_submit('shop', $shop, $form, $form_state);

	$form_state['redirect'] = 'shop/' . $shop->sid;
}

Dumping the $shop object right before field_attach_submit(), it looks like this:

    [sid] => 8
    [type] => my_shop
    [title] => My Shop
    [status] => 1
    [field_my_shop_description] => Array
        (
            [und] => Array
                (
                    [0] => Array
                        (
                            [value] => This is my shop.
                        )

                )

        )

    [uid] => 1
    [revision] => 0
    [language] => und
    [created] => 1337251948
    [default_language] => en
    [last_edit_uid] => 1
    [last_edit_time] => 1337251948
    [vid] => 8

I'm at a loss as to why it will not save my data. I feel like I've got the major fields set, but no matter how I tweak it, even though it saves my entity to the database, it never saves the field data.

Edit: here is hook_entity_info():

function shop_entity_info()
{
	$return['shop'] = array
	(
		'label' => t('Shop'),
		'controller class' => 'jEntityController',
		'base table' => 'shop',
		'language table' => 'shop_language',
		'revision table' => 'shop_data',
		'edit table' => 'shop_edits',
		'uri callback' => 'shop_uri',
		'fieldable' => TRUE,
		'entity keys' => array
		(
			'id' => 'sid',
			'revision' => 'vid',
			'bundle' => 'type',
			'label' => 'title',
		),
		'bundle keys' => array
		(
			'bundle' => 'type',
		),
		'static cache' => TRUE,
		'bundles' => array(),
		'view modes' => array
		(
			'full' => array
			(
				'label' => t('Full content'),
				'custom settings' => FALSE,
			),
			'teaser' => array
			(
				'label' => t('Teaser'),
				'custom settings' => FALSE,
			),
		),
	);
	foreach (shop_types() as $type => $info)
	{
		$return['shop']['bundles'][$type] = array
		(
			'label' => $info->name,
			'admin' => array
			(
				'path' => 'admin/structure/shop/manage/%shop_type',
				'real path' => 'admin/structure/shop/manage/' . str_replace('_', '-', $type),
				'bundle argument' => 4,
				'access arguments' => array('administer shops'),
			),
		);
	}
	return $return;
}

Comments

WorldFallz’s picture

I'm still finding my way around entities, but based on this example it looks like field_attach_submit doesn't actually save the data to the db-- you still need a save function.

jaypan’s picture

It will save the data to the database - I've got another entity that is working, using field_attach_submit() and no special save method. So I'm really not sure why this one doesn't. I tried to track the way through the field code, but couldn't find out where the problem is.

Contact me to contract me for D7 -> D10/11 migrations.

da_solver’s picture

Hi,
I would suggest looking at how the user module saves itself (I.E. as an entity with attached fields).

The user_save method is detailed here;
http://api.drupal.org/api/drupal/modules!user!user.module/function/user_save/7

Note the following sections:

// Invoke presave operations of Field Attach API and Entity API. Those APIs
// require a fully-fledged and updated entity object. Therefore, we need to
// copy any new property values of $edit into it.
foreach ($edit as $key => $value) {
    $account->$key = $value;
}
field_attach_presave('user', $account);

In your scenario, you would use the $form_state['values'][FIELD_NAME] instead of the $edit structure (sorry, I know you know that better than I :). Then later:

field_attach_insert('user', $account);

Same thing, you know, substitute $account for the actual $form_state[....] values. If I'm reading the user_save() method correctly, they are calling field_attach_insert() when they are adding (I.E. inserting) a new user.

For updates, they are using field_attach_update() (e.g. field_attach_update('user', $account)).

Hope that helps (at least a little).
Good Luck.

jienckebd’s picture

I was having the same issue. Adding field_attach_insert() after field_attach_submit() fixed it for me.

Try adding it to your submit handler:

field_attach_submit('shop', $shop, $form, $form_state);
field_attach_insert('shop', $shop);