Hi,
I am actually building a custom entity, this is what my code looks like at the moment:

he_slider.module

<?php

/**
	* Implements hook_entitiy_info()
	*/

function he_slider_entity_info(){
  $slider_info['slider'] = array(
    'label' => t('Slider Item'),
    'controller class' => 'SliderController',
		'views controller class' => 'EntityDefaultViewsController',
    'base table' => 'slider',
    'uri callback' => 'he_slider_uri',
    'fieldable' => TRUE,
    'entity keys' => array(
      'id' => 'sid',
    ),
    'static cache' => TRUE,
    'bundles' => array(
      'slider'=> array(
        'label' => 'Slider',
        'admin' => array(
          'path' => 'admin/structure/slider/manage',
          'access arguments' => array('administer slider'),
        ),
      ),
    ),
    'view modes' => array(
      'full' => array(
        'label' => t('Full Slider Item'),
        'custom settings' =>  FALSE,
      ),
    )
  );
  
  return $slider_info;
}

/**
	* URI Callback function
	*/

function he_slider_uri($slider){
  return array(
    'path' => 'he_slider/' . $slider->sid,
  );
}

/**
	*  Load the a single or multiple entities
	*/

function he_slider_load($sid = NULL, $reset = FALSE){
	$sids = (isset ($sid) ? array($sid) : array());
  $slider = he_slider_load_multiple($sids, $reset);
  return $slider ? reset ($slider) : FALSE;
}

function he_slider_load_multiple($sids = array(), $conditions = array(), $reset = FALSE){
  return entity_load('slider', $sids, $conditions, $reset);
}


/**
	* Provides the Pages to administer and view the entities
	*/

function he_slider_menu(){
	$items['admin/content/slider/add'] = array(
    'title' => 'Add Slider Item',
    'page callback' => 'he_slider_add',
    'access arguments' => array('create slideritem'),
  );
  $items['admin/structure/slider/manage'] = array(
    'title' => 'Slider Administration',
    'description' => 'Manage Slider Structure',
    'page callback' => 'he_slider_info',
    'access arguments' => array('administer slideritem'),
  );
  $items['slider/%he_slider'] = array(
    'title callback' => 'he_slider_page_title',
    'title arguments' => array(1),
    'page callback' => 'he_slider_page_view',
    'page arguments' => array(1),
    'access arguments' => array('view slideritem'),
    'type' => MENU_CALLBACK,
  );
	$items['slider/%he_slider/edit'] = array(
    'title' => 'Slider Edit',
    'title arguments' => array(1),
    'page callback' => 'he_slider_page_edit',
    'page arguments' => array(1),
     'access arguments' => array('edit slideritem'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

function he_slider_permission(){
    return array(
    'administer slideritem' =>  array(
      'title' => t('Administer Slider'),
      'restrict access' => TRUE,
    ),
    'view slideritem' => array(
      'title' => t('View Slideritems'),
    ),
		'edit slideritem' => array(
      'title' => t('Edit Slideritems'),
    )
  );
}

/**
	* Implements the slider view page
	*/

function he_slider_page_view($slider, $view_mode = 'full'){
  $slider->content = array();
	
  // Build fields content.
  field_attach_prepare_view('slider', array($slider->sid => $slider), $view_mode);
  entity_prepare_view('slider', array($slider->sid => $slider));
  $slider->content += field_attach_view('slider', $slider, $view_mode);

  return $slider->content;
}

/**
	* Implements the slider add form, where we are able to create our new entities
	*/

function he_slider_add() {
  $slider = (object) array (
    'sid' => '',
    'type' => 'slider',
		'title' => '',
  );
  
  return drupal_get_form('he_slider_add_form', $slider);
}


function he_slider_add_form($form, &$form_state, $slider) {
	$form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#required' => TRUE,
		'#value' => _he_slider_extrafield_check($slider),
  );
	
	$form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  
  field_attach_form('slider', $slider, $form, $form_state);
  
  return $form;
}

/**
	* Implements a custom function() to check if the extra field got a value
	*/

function _he_slider_extrafield_check($slider) {
	if(isset($slider->title)) {
		$efield = $slider->title;
	} else {
		$efield = '';
	}
	
	return $efield;
}

/**
	* Implements the Entitiy Edit form
	*/
	
function he_slider_page_edit($slider) {
	return drupal_get_form('he_slider_add_form', $slider);
}


/**
	* Implements the administerpage welcome message
	*/

function he_slider_info() {
  return ('Welcome to the administration page for your Slideritems!');
}

function he_slider_page_title($slider){
  return $slider->sid;
}


function he_slider_field_extra_fields() {
  $return = array();
  $return['slider']['slider'] = array(
    'form' => array(
      'title' => array(
        'label' => t('Title'),
        'description' => t('Slider Title'),
      ),
    ),
  );
  return $return;
}

/**
	* Validates the Entity Add form
	*/

function he_slider_add_form_validate($form, &$form_state) {
  $slider_submisttion = (object) $form_state['values'];
  field_attach_form_validate('slider', $slider_submisttion, $form, $form_state);
}

function he_slider_add_form_submit($form, &$form_state) {
  $slider_submission = (object) $form_state['values'];
  field_attach_submit('slider', $slider_submission, $form, $form_state);
  $slider = he_slider_save($slider_submission);
  $form_state['redirect'] = "slider/$slider->sid";
}

function he_slider_save(&$slider) {
  return entity_get_controller('slider')->save($slider);
}

/**
 * Implements hook_views_api().
 */
function he_slider_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'slider') . '/views',
  );
}

/**
* Implements hook_form_alter().
*/
function he_slider_form_alter(&$form, &$form_state, $form_id) {
	if($form_id=='he_slider_add_form'){
    $form['submit']['#weight'] = 99;
  }
}

he_slider.controller

<?php

class SliderController extends EntityAPIController {
    public function save($slider) {
        drupal_write_record('slider', $slider);
        field_attach_insert('slider', $slider);
        module_invoke_all('entity_insert', $slider, 'slider');
        dpm($slider);
        return $slider;
    }
}

Now i am fighting with my Edit form. The way i am actualy doing it, creates a new entity on every edit, and that couldnt be the way it should be done I think.

Anyone got an tipp for me how to do that?

Greetings from germany
Sebastian

Comments

kingandy’s picture

I realise this is four years late, but for the benefit of anyone else having this issue: The problem here is that there's no connection between your $slider input argument and your $slider_submission variable in your submit callback, so it has no way of knowing what database object to update. Without a uniform ID, it can only interpret this as a new object.

First you need to make sure the submit callback has access to the original $slider, by attaching it to either the form or the form_state:

function he_slider_add_form($form, &$form_state, $slider) {
  $form_state['slider_original'] = $slider;
  // ....
}

Then when you come to save the slider, make sure the object you're passing through uses the same ID:

function he_slider_add_form_submit($form, &$form_state) {
  $slider_submission = (object) $form_state['values'];

  $slider_submission->sid = $form_state['slider_original']->sid;
  $slider_submission->type = $form_state['slider_original']->type;

  field_attach_submit('slider', $slider_submission, $form, $form_state);
  $slider = he_slider_save($slider_submission);
  $form_state['redirect'] = "slider/$slider->sid";
}
kingandy’s picture

... though honestly I'm wary of throwing $form_state['values'] in there and THEN doing field_attach_submit. It's probably fine but it might be better to manually populate your custom fields using the original slider as a model:

function he_slider_add_form_submit($form, &$form_state) {
  $slider_submission = $form_state['slider_original'];

  // Update the title manually based on submitted values.
  $slider_submission->title = $form_state['values']['title'];

  field_attach_submit('slider', $slider_submission, $form, $form_state);
  $slider = he_slider_save($slider_submission);
  $form_state['redirect'] = "slider/$slider->sid";
}