1

I'm looking for help in gentle/simple terms for how to add revision information to my custom entities. This is maybe my fifth or sixth attempt to do this and every time I get lost and overwhelmed by all the info in the various online knowledgebases about the various ways of doing things for various iterations of Drupal.

I've used the EntityAPIController (sites/all/modules/entity/includes/entity.controller.inc) from the Entity API module and seen that this has the following method:

  /**
   * Saves an entity revision.
   *
   * @param Entity $entity
   *   Entity revision to save.
   */
  protected function saveRevision($entity) {
    // Convert the entity into an array as it might not have the same properties
    // as the entity, it is just a raw structure.
    $record = (array) $entity;
    // File fields assumes we are using $entity->revision instead of
    // $entity->is_new_revision, so we also support it and make sure it's set to
    // the same value.
    $entity->is_new_revision = !empty($entity->is_new_revision) || !empty($entity->revision) || $entity->is_new;
    $entity->revision = &$entity->is_new_revision;
    $entity->{$this->defaultRevisionKey} = !empty($entity->{$this->defaultRevisionKey}) || $entity->is_new;



    // When saving a new revision, set any existing revision ID to NULL so as to
    // ensure that a new revision will actually be created.
    if ($entity->is_new_revision && isset($record[$this->revisionKey])) {
      $record[$this->revisionKey] = NULL;
    }

    if ($entity->is_new_revision) {
      drupal_write_record($this->revisionTable, $record);
      $update_default_revision = $entity->{$this->defaultRevisionKey};
    }
    else {
      drupal_write_record($this->revisionTable, $record, $this->revisionKey);
      // @todo: Fix original entity to be of the same revision and check whether
      // the default revision key has been set.
      $update_default_revision = $entity->{$this->defaultRevisionKey} && $entity->{$this->revisionKey} != $entity->original->{$this->revisionKey};
    }
    // Make sure to update the new revision key for the entity.
    $entity->{$this->revisionKey} = $record[$this->revisionKey];

    // Mark this revision as the default one.
    if ($update_default_revision) {
      db_update($this->entityInfo['base table'])
        ->fields(array($this->revisionKey => $record[$this->revisionKey]))
        ->condition($this->idKey, $entity->{$this->idKey})
        ->execute();
    }
    return $entity->is_new_revision ? SAVED_NEW : SAVED_UPDATED;
  }

But with all the various sources of information out there on developing for Drupal I'm in a total tangle with my understanding. Am I just supposed to say "is revisionable" this link and others kind of gloss over it as though all one needs to do is set the "revision table" and "entity keys" "revision" element in the hook_entity_info implementation

This is where I'm unstuck - just as with node and node_revision in the db, can't entity and entity revision tables be different? Surely we need to overwrite something in one of the entity/controller/wrapper classes because it's not as simple as just copying all fields from one db table to another and auto incrementing a version id?

This post has lots of info, but I started reading through the links under "documentation" and I'm worried that I might be looking at some module which has hijacked the term revision in some higher layer.

1

So far this seems to be the best example to follow/debug and learn from, others just seem to lack that crucial sentance that actually helps to see what's going on: https://www.drupal.org/project/typical_entity_example

Use typical_entity_example_5 and note the work on .install and .module. The key elements are in hook_entity_info (.module)/ hook_schema (.install) and the typical_entity_example_5_form_submit(...) (.admin.inc) function where we have:

$entity = $form_state['typical_entity_example_5'];
entity_form_submit_build_entity('typical_entity_example_5', $entity, $form, $form_state);
$entity->is_new_revision = TRUE;
$wrapper = entity_metadata_wrapper('typical_entity_example_5', $entity);
$wrapper->save();

The power of this example is that the form of the schemas are more or less the same, but with differences in the columns used as primary keys.

I'm still trying to work out though whether it's better to have it in ->save() rather than using it in the admin form submit as above. So that any and every save invocation creates a new entity. Programmatical (non aforementioned admin UI) editing of an entity would presumably not create a new revision unless manually coded in.

NOTE: you can put it in either the custom entity class:

class YourClass extends Entity {
    public function save() {
        $this->is_new_revision = TRUE;
        parent::save();
    }
}

or custom controller:

class YourClassController extends EntityAPIController {
    public function save($entity, $transaction = NULL) {
        $entity->is_new_revision = TRUE;
        return parent::save($entity, $transaction);
    }
}

Or both, I guess. I'm still not 100% sure if there are use cases which neglect one way or another as from what I've seen so far it goes YourClass->save() >> into >> YourClassController->save() so I suppose I'll probably just put it in both just to be sure...

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.