0

I'm doing some work around the Salesforce Suite in Drupal 7. It's a suite of modules that load the Salesforce REST API, map objects and fields between Drupal and Salesforce, push data from Drupal to WordPress, pull data down from Salesforce, manage queues for the data, etc.

I'm trying to understand how Drupal handles a flag called salesforce_pull (from the salesforce_pull module within the Salesforce Suite). This code runs when Drupal knows about a new Salesforce row (presumably on cron or on an Ajax call):

  try {
  // Create entity from mapping object and field maps.
  $entity_info = entity_get_info($sf_mapping->drupal_entity_type);

  // Define values to pass to entity_create().
  $values = array();
  if (isset($entity_info['entity keys']['bundle']) &&
    !empty($entity_info['entity keys']['bundle'])
  ) {
    $values[$entity_info['entity keys']['bundle']] = $sf_mapping->drupal_bundle;

    // Because creating term via entities actually needs vid and won't be
    // fixed in Entity API (https://www.drupal.org/node/1409256).
    if (isset($values['vocabulary_machine_name'])) {
      $vocabulary = taxonomy_vocabulary_machine_name_load($values['vocabulary_machine_name']);
      $values['vid'] = $vocabulary->vid;
    }
  }
  else {
    // Not all entities will have bundle defined under entity keys,
    // e.g. the User entity.
    $values[$sf_mapping->drupal_bundle] = $sf_mapping->drupal_bundle;
  }

  // See note above about flag.
  $values['salesforce_pull'] = TRUE;

  // Create entity.
  $entity = entity_create($sf_mapping->drupal_entity_type, $values);

  // Flag this entity as having been processed. This does not persist,
  // but is used by salesforce_push to avoid duplicate processing.
  $entity->salesforce_pull = TRUE;
  $wrapper = entity_metadata_wrapper($sf_mapping->drupal_entity_type, $entity);

  salesforce_pull_map_fields($sf_mapping->field_mappings, $wrapper, $sf_object);

A comment there says "// See note above about flag." but the only thing I found was the same flag for other events (update, delete of Salesforce rows). It looks like this (which is fine, but I still am unclear how it works/how to use it):

// Flag this entity as having been processed. This does not persist,
// but is used by salesforce_push to avoid duplicate processing.
$entity->salesforce_pull = TRUE;

That part about salesforce_push using it is what I'd like to understand.

I have not found a database field for salesforce_pull (on any of the entities). I've also done a database search (through phpMyAdmin so it could search the whole thing) for TRUE values and the salesforce_pull phrase with nothing that seems to be related to this, including in the cache tables.

It seems like the Fields API (at least in D7) has a way to save data that doesn't have a corresponding field in the database. If this is the case, where does the field get saved? How long does it stay before it gets reset? How does it get reset? How do I access it?

I'd like to be able to use this convention, but I don't understand how it works and haven't been able to find any documentation on it.

2

Interesting question, had a quick read through the module's code. I came across this comment that should answer your question:

@salesforce_pull.module:335

// Flag this entity as having been processed. This does not persist,
// but is used by salesforce_push to avoid duplicate processing.
$entity->salesforce_pull = TRUE;

It seems that this is not an entity field (or rather an entity property) that is attached to an entity (and therefore stored in the db), but, as the above comment mentions, simply a short-lived flag.

The way this goes is like this:

  1. The salesforce_pull module sets the flag on an entity (see @salesforce_pull.module:335)
  2. salesforce_pull conditionally wraps that entity in an entity_wrapper object and calls the ->save() function on the object (see @salesforce_pull.module:341)
  3. This call will call hook_entity_update implementations, including the one from salesforce_push (see @salesforce_push.module:20)
  4. salesforce_push will call the salesforce_push_entity_crud function that checks the value of that flag before using the Salesforce API to sync data (see @salesforce_push.module:44)

All the steps above take place in the same request, which is why persisting the flag is not required.

Hope this helps, good luck!

| improve this answer | |
  • Thanks. Do you have an understanding of how this kind of short-lived flag works, or somewhere that I can learn about them? How long do they get stored (like are they in a cache somewhere, maybe)? How can they be accessed? I ask because the salesforce_push module checks for the existence of this flag, so it must be accessible somehow? – Jonathan Stegall Sep 20 '16 at 16:16
  • 1
    It's a property of the object @Jonathan. Within the same request, and assuming another process doesn't remove it, the property will be available when other code uses the same object. It's not stored anywhere except the memory allocated to that request – Clive Sep 20 '16 at 16:33
  • Updated the answer, have a look at the steps. – Stefanos Petrakis Sep 20 '16 at 16:35

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.