You are here

function _field_encrypt_field_storage_pre_update in Field Encryption 7

Implements hook_field_storage_pre_update().

1 call to _field_encrypt_field_storage_pre_update()
field_encrypt_field_storage_pre_update in ./field_encrypt.module
Implements hook_field_storage_pre_update().

File

./field_encrypt.inc, line 140
Encryption functionality for the Field encrypt module.

Code

function _field_encrypt_field_storage_pre_update($entity_type, $entity, &$skip_fields) {
  static $field_info = NULL;
  if ($field_info === NULL) {
    $field_info = field_info_field_by_ids();
  }
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
  if (is_null($vid)) {
    $vid = $id;
  }
  $default_options = array(
    'default' => FALSE,
    'deleted' => FALSE,
    'language' => NULL,
  );
  $instances = _field_invoke_get_instances($entity_type, $bundle, $default_options);
  foreach ($instances as $instance) {

    // Get the field data.
    $field_id = $instance['field_id'];
    $current_field_info = $field_info[$field_id];

    // Are we encrypting this field?
    if (!isset($current_field_info['settings']['field_encrypt']['encrypt']) || !$current_field_info['settings']['field_encrypt']['encrypt']) {

      // Encryption setting is set to FALSE, skip it.
      continue;
    }
    $field_name = $instance['field_name'];
    $data_table = key($current_field_info['storage']['details']['sql'][FIELD_LOAD_CURRENT]);
    $revision_table = key($current_field_info['storage']['details']['sql'][FIELD_LOAD_REVISION]);

    // We're bypassing usual storage, mark field for skipping.
    $skip_fields[$field_id] = $current_field_info;

    // If there's nothing in the field, go no further.
    if (empty($entity->{$field_name})) {
      continue;
    }

    // Now we need to insert the data, we can't do multiple merges so we have to
    // do each language/delta separately.
    foreach ($entity->{$field_name} as $language => $items) {

      // Delete and Insert, like field_sql_storage_field_storage_write() does.
      db_delete($data_table)
        ->condition('entity_id', $id)
        ->condition('entity_type', $entity_type)
        ->condition('revision_id', $vid)
        ->execute();
      db_delete($revision_table)
        ->condition('entity_id', $id)
        ->condition('entity_type', $entity_type)
        ->condition('revision_id', $vid)
        ->execute();
      foreach ($items as $delta => $item) {
        $merge_keys = array(
          'entity_type' => $entity_type,
          'bundle' => $bundle,
          'deleted' => 0,
          'entity_id' => $id,
          'language' => $language,
          'delta' => $delta,
        );
        $fields = array(
          'revision_id' => $vid,
        );
        foreach ($current_field_info['storage']['details']['sql'][FIELD_LOAD_CURRENT][$data_table] as $column => $field) {
          if (isset($item[$column]) && !empty($item[$column])) {
            $fields[$field] = !isset($current_field_info['indexes'][$column]) ? field_encrypt_encrypt($item[$column]) : $item[$column];
          }
        }

        // Put data in data table.
        db_merge($data_table)
          ->key($merge_keys)
          ->fields($fields)
          ->execute();

        // Put data in revision table.
        $merge_keys['revision_id'] = $vid;
        unset($fields['revision_id']);
        if (!empty($fields)) {
          db_merge($revision_table)
            ->key($merge_keys)
            ->fields($fields)
            ->execute();
        }
      }
    }
  }
}