You are here

public function ProcessEntities::encryptEntity in Field Encryption 3.0.x

Encrypts an entity's encrypted fields.

Parameters

\Drupal\Core\Entity\ContentEntityInterface $entity: The entity to encrypt.

See also

field_encrypt_entity_presave()

field_encrypt_entity_update()

field_encrypt_entity_insert()

field_encrypt_module_implements_alter()

File

src/ProcessEntities.php, line 52

Class

ProcessEntities
Service class to process entities and fields for encryption.

Namespace

Drupal\field_encrypt

Code

public function encryptEntity(ContentEntityInterface $entity) {

  // Make sure there is a base field to store encrypted data.
  if (!$entity
    ->hasField(static::ENCRYPTED_FIELD_STORAGE_NAME)) {
    return;
  }

  // Check if encryption is prevent due to implementations of
  // hook_field_encrypt_allow_encryption().
  foreach ($this->moduleHandler
    ->getImplementations('field_encrypt_allow_encryption') as $module) {
    $result = $this->moduleHandler
      ->invoke($module, 'field_encrypt_allow_encryption', [
      $entity,
    ]);

    // If the implementation returns a FALSE boolean value, disable
    // encryption.
    if ($result === FALSE) {
      return;
    }
  }

  // Process all language variants of the entity.
  $languages = $entity
    ->getTranslationLanguages();
  foreach ($languages as $language) {
    $translated_entity = $entity
      ->getTranslation($language
      ->getId());
    $field = $translated_entity
      ->get(static::ENCRYPTED_FIELD_STORAGE_NAME);

    // Before encrypting the entity ensure the encrypted field storage is
    // empty so that any changes to encryption settings are processed as
    // expected.
    if (!$field
      ->isEmpty()) {
      $field
        ->removeItem(0);
      $field
        ->appendItem();
    }
    foreach ($this
      ->getEncryptedFields($translated_entity) as $field) {
      $this
        ->encryptField($translated_entity, $field);
    }

    // The entity storage handler has clever logic to ensure that configurable
    // fields are only saved if necessary. If entity->original is set we need
    // to ensure the field values are the values in the database and not the
    // unencrypted values so that they are saved if necessary. This is
    // particularly important when a previously encrypted field is set to be
    // unencrypted.
    // @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage::saveToDedicatedTables()
    // @see \Drupal\Core\Entity\ContentEntityStorageBase::hasFieldValueChanged()
    if (isset($translated_entity->original) && $translated_entity->original instanceof ContentEntityInterface) {
      if ($translated_entity->original
        ->hasTranslation($language
        ->getId())) {
        $translated_original = $translated_entity->original
          ->getTranslation($language
          ->getId());
        $this
          ->setEncryptedFieldValues($translated_original, 'getUnencryptedPlaceholderValue');
      }
    }

    // All the encrypted fields have now being processed and their values
    // moved to encrypted field storage. It's time to encrypt that field.
    $translated_entity
      ->get(static::ENCRYPTED_FIELD_STORAGE_NAME)[0]
      ->encrypt();
  }
}