3

Edit: My question is similar to How to create multi-value, multi-bundle entity reference fields in code?, except the field doesn't need to reference multiple bundles.

We have an existing view of custom entities. The view needs to now be filtered based on some related fields that are not part of the entity (or any entity). Kind of like adding a Taxonomy Reference field to a Content Type. What is the best way to add those fields to the entity?

I see that many modules use attachLoad to attach fields to an entity, but when I try my implementation those fields don't show up in my list of Fields or Filters in Views.

This is a screenshot of the checkboxes field:

enter image description here

This is my controller:

class ContactsController extends EntityAPIController {

  public function attachLoad(&$queried_entities, $revision_id = FALSE)
  {
    foreach ($queried_entities as $key => $entity)
    {
      $queried_entities[$key]->foo = "bar";
    }
    parent::attachLoad($queried_entities, $revision_id);
  }

}

And this is my hook_entity_info:

function contacts_entity_info() {
  $return = array(
    'contacts' => array(
      'label' => t('Contact'),
      'entity class' => 'Contacts',
      'controller class' => 'ContactsController',
      'views controller class' => 'ContactsViewsController',
      'base table' => 'contacts',
      'fieldable' => TRUE,
      'entity keys' => array(
        'id' => 'ckid',
        'bundle' => array(),
      ),
      'bundle keys' => array(),
      'bundles' => array(),
      'load hook' => 'contacts_load',
      'view modes' => array(
        'full' => array(
          'label' => t('Default'),
          'custom settings' => FALSE,
        ),
      ),
      'label callback' => 'entity_class_label',
      'uri callback' => 'entity_class_uri',
      'module' => 'contacts',
      'access callback' => 'contacts_access',
    ),
  );

  return $return;
}

This is a suggested implementation of EntityDefaultViewsController:

/**
* EntityTest Views Controller class.
*/
class ContactsViewsController extends EntityDefaultViewsController {

  /**
   * Add extra fields to views_data().
   */
  public function views_data() {
    $data = parent::views_data();

    // Add your custom data here
    $data['contacts_topics']['table'] = array(
      'group' => t('Contacts Topics'),
      'base' => array(
        'field' => 'ckid',
        'title' => t('Contacts Topics'),
      ),
      'join' => array(
        'contacts' => array(
          'left_field' => 'ckid',
          'field' => 'ckid',
        ),
      ),
    );

    $data['contacts_topics'] = array(
      'ckid' => array(
        'title' => 'Contact Entity ID',
        'field' => array(
          'handler' => 'views_handler_field_numeric',
          'click sortable' => TRUE,
        ),
        'sort' => array(
          'handler' => 'views_handler_sort',
        ),
        'filter' => array(
          'handler' => 'views_handler_filter_numeric',
        ),
        'relationship' => array(
          'base' => 'contacts',
          'base field' => 'ckid',
          'handler' => 'views_handler_relationship',
          'label' => t('Contact entity relationship'),
          'title' => t('Conact entity relationship'),
        ),
      ),
    );

    return $data;
  }
}

Unfortunately I don't see anything in the Views SQL that shows that any of these attempts to add the fields or join the topics table to the contacts table are working.

  • how are these un-related fields 'related' to your entity. How do these entities know to show X other fields in addition to their own?? – tenken Dec 12 '12 at 18:53
  • There is no entity relationship between them, it's simply an extraneous table I've defined in schema. It's a many-to-many relationship, so each contact can have many topics. The examples I've seen is simply a many-to-one example, and the deadline is ticking :( – Johnathan Elmore Dec 12 '12 at 22:02
  • It's kind of like I want to add a taxonomy field to this entity, so users can select any different kind of topics they are interested in, but I don't want to define a separate field for each topic... – Johnathan Elmore Dec 12 '12 at 22:19
  • I just found the Relation module... I'm thinking this might be what I'm looking for – Johnathan Elmore Dec 12 '12 at 22:42
  • Relation was very quick and easy to get going, but the problem is that the Views integration didn't go far enough to provide the related entity as a Filter... going back to the beginning again. – Johnathan Elmore Dec 13 '12 at 17:59
3

How to attach a field to an entity programically solved this problem for me. It's not an exact duplicate, but the answer and the comments pointed me to the right direction.

So this code creates the field and the instance and it attaches it to the entity very nicely:

function contacts_enable()
{
  if (!field_info_field('related_topics'))
  {
    $field = array(
      'field_name' => 'related_topics',
      'type' => 'list_text',
      'cardinality' => -1,
      'settings' => array(
        'allowed_values_function' => '_contacts_get_related_topics',
      ),
    );

    field_create_field($field);

    $instance = array(
      'field_name' => 'related_topics',
      'entity_type' => 'contacts',
      'label' => 'Related Topics',
      'bundle' => 'contacts',
      'default_value' => NULL,
      'settings' => array(
        'user_register_form' => FALSE,
      ),
      'widget' => array(
        'active' => 1,
        'module' => 'options',
        'settings' => array(),
        'type' => 'options_buttons',
        'weight' => -1,
      ),
    );

    field_create_instance($instance);
  }
}
  • Nice one Jonathan, thanks. In case somebody is wondering, if you use a structure like the Model project to create entities, a good point to place the above code (properly adapted of course) would be function save of ModelTypeController (which is based on EntityAPIControllerExportable). – Wtower Feb 11 '14 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.