drupal实体实现,某处有一个错误

I'm just starting out with drupal and I am poking around with the entity API. I've tried to write an implementation that is not meant for production, just as a test case.

But I can't get it to work. When I try to save a new candidate I get an error message: Creating default object from empty value in entity_form_submit_build_entity() (line 8213 of /wwwroot/drupal/public_html/includes/common.inc).

The entity is not being added to the database. It's probably a stupid error but I can't track it down. So if anyone with more experience could help me out I would be very grateful.

the audition.module file:

<?php
###DATABASE SCHEMAS
function audition_schema(){
  $schema['audition_candidate'] = array(
    'description'=>'stores all the candidates for an audition',
    'fields'=>array(
      'id'=>array(
        'description'=>'identifier for candidate',
        'type'=>'serial',
        'not null'=>TRUE,
        'unsigned'=>TRUE,
      ),
      'lastname'=>array(
        'description'=>'candidate last name',
        'type'=>'varchar',
        'length'=>'50',
        'not null'=>TRUE,
      ),
      'firstname'=>array(
        'description'=>'candidate first name',
        'type'=>'varchar',
        'length'=>'50',
        'not null'=>TRUE,
      ),
      'mailadress'=>array(
        'description'=>'candidate mail adress',
        'type'=>'varchar',
        'length'=>'255',
        'not null'=>TRUE,
      ),
      'vocalgroup'=>array(
        'description'=>'candidate vocal group type',
        'type'=>'int',
        'length'=>'small',
        'not null'=>TRUE,
      ),
    ),
    'primary key' =>array('id'),
    'label' => array('lastname','firstname'),
  );

  $schema['vocal_group'] = array(
    'description'=>'Stores the different vocal groups',
    'fields'=>array(
      'id'=>array(
        'description'=>'identifier for vocal group',
        'type'=>'serial',
        'not null'=>TRUE,
        'unsigned'=>TRUE,
      ),
      'group'=>array(
        'description'=>'vocal group name',
        'type'=>'varchar',
        'length'=>'50',
        'not null'=>TRUE,
      ),
    ),
    'primary key' =>array('id'),
    'uri callback' => 'entity_class_uri',
  );

  return $schema;
}

###ENTITIES
function audition_entity_info(){

  $entity['candidate']= array(
    'label'=>t('Audition candidate'),
    'plural label'=>t('Audition candidates'),
    'base table' => 'audition_candidate',
    'entity class' => 'CandidateEntity',
    'entity keys' => array(
      'id'=>'id',
      'label' => 'lastname'),
    'admin ui' => array(
      'path' => 'admin/candidate',
      'controllerclass' => 'EntityDefaultUIController',
      'menu wildcard' => '%candidate',
      'file' => 'candidate.admin.inc',
    ),
    'module' => 'audition',
    'access callback' => 'candidate_access_callback',
  );

  $entity['vocalgroup'] = array(
    'label' => t('Audition candidate vocal group'),
    'plural label' => t('Vocal groups'),
    'base table' => 'vocal_group',
    'entity keys' => array(
      'id'=>'id',
    ),
  );



  /*dsm($entity);*/
  return $entity;
}

class CandidateEntity extends Entity {
  protected function defaultUri() {
    return array('path' => 'candidate/' . $this->identifier());
  }
}

function candidate_access_callback($op, $candidate = NULL, $account= NULL){
  if($op == 'view' && user_access('view_candidates',$account))
  {
    return TRUE;
  }
  else if(user_access('administer_candidates',$account))
  {
    return TRUE;
  }

  return FALSE;
}

###INSTALL SCRIPT


###PERMISSIONS
function audition_permission(){
  $permission['administer_candidates'] = array(
    'title' => t('Edit candidates'),
    'description' => t('Can make changes to candidate date'),
  );

  $permission['view_candidates'] = array(
    'title'=> t('View candidates'),
    'description' => t('Can view all candidates')
  );

  return $permission;
}

###MENU HOOKS
function audition_menu(){


  $menuitems['audition'] = array(
    'page callback'=> 'audition_page',
    'access callback' => TRUE,
  );

  $menuitems['candidate/%candidate'] = array(
    'title' => 'Audition candidate',
    'page callback' => 'candidate_entity_view',
    'page arguments' => array(1),
    'access callback' => TRUE,
  );

  return $menuitems;
}

###PAGE CALLBACK FUNCTIONS
  function audition_page() {
    $candidate= entity_load('candidate', array(1));
    /*dsm($candidate);*/

    return 'test';
  }

  function candidate_load($candidateid)
  {
    $candidate = entity_load('candidate',array($candidateid));
    dsm($candidate);
    return array_pop($candidate);
  }

  function candidate_entity_view($candidate)
  {
    return 'test';
  }

and this is the candidate.admin.inc:

  <?php

/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

function candidate_form($form, &$form_state, $candidate){
  $form['lastname'] = array(
    '#title' => t('last name'),
    '#type' => 'textfield',
    '#default_value' => isset($candidate->lastname) ? $candidate->lastname : '',
    '#description' => 'Fill out your last name',
    '#required' => TRUE,
  );
  $form['firstname'] = array(
    '#title' => t('first name'),
    '#type' => 'textfield',
    '#default_value' => isset($candidate->firstname) ? $candidate->firstname : '',
    '#description' => 'Fill out your first name',
    '#required' => TRUE,
  );
  $form['mailadress'] = array(
    '#title' => t('mailadress'),
    '#type' => 'textfield',
    '#default_value' => isset($candidate->mailadress) ? $candidate->mailadress : '',
    '#description' => 'Fill out a valid mailadress',
    '#required' => TRUE,
  );
    $form['vocalgroup'] = array(
    '#title' => t('vocal group'),
    '#type' => 'textfield',
    '#default_value' => isset($candidate->vocalgroup) ? $candidate->vocalgroup : '',
    '#description' => 'To wich vocal group do you belong?',
    '#required' => TRUE,
  );
    $form['actions'] = array(
      '#type' => 'actions',
      'submit' => array(
        '#type' => 'submit',
        '#value' => t('Submit'),
      ),
    );

  return $form;

}

function candidate_form_submit($form, &$form_state){

  $candidate = entity_ui_form_submit_build_entity($form, $form_state);
  dsm($candidate);
  $candidate->Save();

  drupal_set_message(t('You created a candidate'));
  $form_state['redirect'] = 'admin/candidate';
}