Problem/Motivation

It can sometimes be advantageous to relate two Drupal entities based on a foreign key relationship between properties in their base table. One example of this is with the use of the Data module, where tables of data may be adopted, but often these can be derived from Drupal tables, views, or simply imported data with some known relationship to Drupal. Also, sometimes one may wish to link pieces of data on an un-conventional manner, not supported by Entity Reference, for example, timeseries data. When working with timeseries data it can be useful to allow simultaneous editing of data that occurs on the same date/timestamp, rather than some common entity ID attribute.

Proposed resolution

Introduce a simple getter "fk_getter" for foreign key relationships between two Entity base tables.

Remaining tasks

  • Initial Coding
  • Initial Testing by developer
  • Review & testing by others
  • Documentation

User interface changes

None

API changes

None

Data model changes

None

Original report by [username]

n/a

Comments

robertwb created an issue. See original summary.

robertwb’s picture

Status: Active » Needs review
StatusFileSize
new1.26 KB

Adding an initial patch here to see if there is any wider spread interest. The patch works as advertised, tested on 2 installs that I maintain. The specification of the PK & FK fields is currently a text box, which definitely needs to be a drop-down select for security and stability, but for testing purposes this works.

I am having trouble adding the include file that powers this getter, however. I followed the instructions on , but cannot seem to get it t o add the file contents to the diff. I am pasting it below, and would be delighted to get some guidance from someone.


<?php
/**
 * @file
 *  Contains class for an entity that is linked to the base entity by an FK column (could be a field or other)
 */

/**
 * Form Entity that loads an entity from an id stored in config.
 */
class FlexiformFormFKEntityLoad extends FlexiformFormEntityBase {

  /**
   * {@inheritdoc}
   */
  public function getEntity() {

    $id = $this->settings['entity_id'];

    // Don't do anything if the $id is empty.
    if (empty($id)) {
      return FALSE;
    }
    
    parent::getEntity();
    $base = $this->manager->getBaseEntity();
    $bt = $this->manager->getEntityType('base_entity');
    list($baseid, $rid, $bun) = entity_extract_ids($bt, $base);
    dpm($base, "Base Entity");
    $efq = new EntityFieldQuery(); 
    $efq->entityCondition('entity_type', $this->entity_type);
    $efq->propertyCondition($this->settings['fk_col'], $baseid, '=');
    drupal_set_message("entityCondition('entity_type', $this->entity_type)");
    drupal_set_message($this->settings['fk_col'] . ", $baseid, '='");
    $result = $efq->execute();
    dpm($result, "efq: ");
    if (isset($result[$this->entity_type])) {
      $rez = array_shift($result[$this->entity_type]);
      if (property_exists($rez, $this->settings['pk_col'])) {
        $id = $rez->{$this->settings['pk_col']};
    dpm($id, "pkid: ");
        $valid = TRUE;
      }
    }
    // Don't do anything if the $id is empty.
    if (empty($id)) {
      return FALSE;
    }

    $entity = entity_load_single($this->entity_type, $id);
    return $this->checkBundle($entity) ? $entity : FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function configForm($form, &$form_state) {
    $form = parent::configForm($form, $form_state);

    $form['settings']['fk_col'] = array(
      '#type' => 'textfield',
      '#title' => t('Foreign Key Column'),
      '#description' => t('the column referring this to the base entity.'),
      '#default_value' => !empty($this->settings['fk_col']) ? $this->settings['fk_col'] : '',
      '#required' => TRUE,
    );
    $form['settings']['pk_col'] = array(
      '#type' => 'textfield',
      '#title' => t('Primary Key Column'),
      '#description' => t('the column referring this to the base entity.'),
      '#default_value' => !empty($this->settings['pk_col']) ? $this->settings['pk_col'] : '',
      '#required' => TRUE,
    );

    return $form;
  }
}


rlmumford’s picture

Status: Needs review » Needs work

Hi robertwb, your patch doesn't include the class you're trying to add. I suggest you put it in the fk.form_entity.inc underneath includes/form_entity and add that to the modules .info file.

The class you have copied into your comment is exactly the same as class that already exists in the module and, in Drupal 7, all classes need to have unique names. This may be why you can't get the class to load.

I hope that helps.

robertwb’s picture

Hey @rlmumford - thanks for the response and sorry to delay so long before getting back to this. The class name duplication that you pointed out, I accidentally pasted the wrong code in here, and so that is not a problem. In the interim, I also figured out how to get a new file added to a git patch, so, I moved past that step as well. I still have some bugs to work through on this, but will be following back. Thanks again.

robertwb’s picture

Issue summary: View changes
robertwb’s picture

StatusFileSize
new3.86 KB

Attached patch adds include files and necessary adjustments to the .info and .inc files to enable for all installs. This is a very simple implementation that assumes the table to be joined:

  1. Has a field that points to the Entity_ID field of the current flexiform base entity, described as "Foreign Key" in config form.
  2. Has it's own unique identifier field, described as "Primarey Key" in config form.

Potential application of this with Data module to provide editing.

robertwb’s picture

Status: Needs work » Needs review