Hello, i tried to make use of *UIController to avoid writing all hook menus and calling myself all field_attach* functions.

I created a bundable entity type, and i want a admin ui controller that will display , for this entity
- overview form with view and edit link
- an add page

When i use EntityDefaultUIController :
- i have the overview page, and edit link is working.
- view page is "not found"
- add page fails, because entity API does not fill $entity->{bundle_property}, so i can't display form (except if my entity has no bundles, that's to say only on bundle with the name of the entity.
I suppose that's because in this case, url does not contains bundle name in url; so at one moment entity_extract_ids is complaining ( by complaining, i mean it breaks the site :D )

When i use EntityContentUIController :
- all the same

When is use EntityBundleableUIController :
- add link is working ! (and also edit link) entity bundle is part of the "add' url, i suppose that's why this now working
- overview page disappears ... deleted by EntityDefaultUIController that is unsettings $items[$this->path] (why ??)
- my view page is still not found

Here is my hook_entity_info :


function okclicence_entity_info() {
  $return['okclicence'] = array(
    'label' => t('OKC Licence'),
    'base table' => 'okclicence', // corresponds to hook_schema
    'uri callback' => 'entity_class_uri', // only a way to set uri in okclicenceEntity
    'label callback' => 'entity_class_label',
    'entity class' => 'okclicenceEntity',
    'controller class' => 'entityAPIController', // use entity API controller for CRUD operations and more on entities
    'fieldable' => TRUE, // allow to attache fields from FIELD API
    'entity keys' => array(
      'id' => 'id', // needed by entity_load
      'bundle' => 'type', // utilisé par field_attach api pour charger les fields attachés
      'label' => "OKC Licence", // DO NOT FORGET, may cause fatal errors, yay !
    ),
    'access callback' => 'okclicence_access',
    'module' => 'okclicence',  // to help automatic declaration to views and other contrib module.
    // Enable the entity API's admin UI.
    'admin ui' => array(
      'path' => 'admin/commerce/okclicences',
      'controller class' => 'EntityBundleableUIController',
      'file' => 'okclicence.admin.inc',
    ),
    // bundle informations
    'bundle keys' => array(
      'bundle' => 'type',
    ),
  );

  // list existing bundles type for okclicence
  $types = okclicence_get_types();
  if ($types) {
    foreach ($types as $name => $type) {
      $return['okclicence']['bundles'][$name] = array(
        'label' => $type->label,
      );
    }
  }

  // The entity that holds information about the entity types	  
  $return['okclicencetype'] = array(
    'label' => t('OKC Licence Type'),
    'entity class' => 'okclicencetypeEntity',
    'exportable' => TRUE,
    'controller class' => 'EntityAPIControllerExportable',
    'base table' => 'okclicencetype',
    'bundle of' => 'okclicence', // entity type use this special key when entity is bundle of another.
    'fieldable' => FALSE,
    'entity keys' => array(
      'id' => 'id',
      'name' => 'name',
      'label' => 'OKC licence type'
    ),
    'access callback' => 'okclicencetype_access',
    'module' => 'okclicence',
    'admin ui' => array(
      'path' => 'admin/commerce/config/okclicencetypes',
      'controller class' => 'EntityContentUIController',
      'file' => 'okclicence.admin.inc',
    ),
    'label callback' => 'entity_class_label',
    'uri callback' => 'entity_class_uri',
  );
  return $return;
}

And here is my hook_schema :

/**
 * Implements hook_schema().
 */
function okclicence_schema() {
  $schema = array();

  $schema['okclicence'] = array(
    'description' => 'The base table for okclicence entities.',
    'fields' => array(
      'id' => array(
        'description' => 'Primary Key: Identifier for a okclicence.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'type' => array(
        'description' => 'The {okclicence_type}.type of this okclicence.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'created' => array(
        'description' => 'The Unix timestamp when the okclicence was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'changed' => array(
        'description' => 'The Unix timestamp when the okclicence was most recently saved.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'starts' => array(
        'type' => 'datetime',
        'mysql_type' => 'datetime',
        'pgsql_type' => 'timestamp without time zone',
        'sqlite_type' => 'varchar',
        'sqlsrv_type' => 'smalldatetime',
        'not null' => FALSE,
        'sortable' => TRUE,
        'views' => TRUE,
        'description' => 'The Unix timestamp when the okclicence will start.',
      ),
      'uid' => array(
        'description' => 'The {users}.uid that created this license belongs to.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'product_id' => array(
        'description' => 'The {commerce_product}.product_id that is licensed.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'status' => array(
        'description' => 'The license status.',
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
        'default' => 0,
      ),
      'expires' => array(
        'description' => 'The Unix timestamp when the license expires. 0 for never.',
        'type' => 'datetime',
        'mysql_type' => 'datetime',
        'pgsql_type' => 'timestamp without time zone',
        'sqlite_type' => 'varchar',
        'sqlsrv_type' => 'smalldatetime',
        'not null' => FALSE,
        'sortable' => TRUE,
        'views' => TRUE,
      ),
      'expires_automatically' => array(
        'description' => 'Whether the module should expire the license automatically.',
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
        'default' => 1,
      ),
    ),
    'primary key' => array('id'),
    'indexes' => array(
      'type' => array('type'),
    ),
  );

  $schema['okclicencetype'] = array(
    'description' => 'Stores information about all defined entity_test types.',
    'fields' => array(
      'id' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique entity_test type ID.',
      ),
      'name' => array(
        'description' => 'The machine-readable name of this entity_test type.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
      ),
      'label' => array(
        'description' => 'The human-readable name of this entity_test type.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'weight' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
        'description' => 'The weight of this entity_test type in relation to others.',
      ),
      'locked' => array(
        'description' => 'A boolean indicating whether the administrator may delete this type.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
      ),
      'data' => array(
        'type' => 'text',
        'not null' => FALSE,
        'size' => 'big',
        'serialize' => TRUE,
        'description' => 'A serialized array of additional data related to this entity_test type.',
        'merge' => TRUE,
      ),
      'status' => array(
        'type' => 'int',
        'not null' => TRUE,
        // Set the default to ENTITY_CUSTOM without using the constant as it is
        // not safe to use it at this point.
        'default' => 0x01,
        'size' => 'tiny',
        'description' => 'The exportable status of the entity.',
      ),
      'module' => array(
        'description' => 'The name of the providing module if the entity has been defined in code.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('id'),
    'unique keys' => array(
      'name' => array('name'),
    ),
  );

  return $schema;
}

Comments

nyl_auster’s picture

Category: Support request » Bug report
TBarina’s picture

Same here: overview page disappears; this is due to the unset($items[$this-path]) in EntityContentUIController's "hook_menu" public function.

Is this really necessary?

KThxBye

garphy’s picture

I would love some clarification on this, too.

Why does the EntityContentUIController unset $items[$this->path] ?

It forces to reimplement manually the listing administrative UI whereas the one provided by EntityDefaultUIController works perfectly...

darby3’s picture

Hello from 2022...where this post answered my question...!