aeliot/doctrine-encrypted-contracts
Installation
composer require aeliot/doctrine-encrypted-contracts
Ensure your project uses Doctrine ORM (v2.10+) and PHP 8.1+.
First Use Case
Extend the Aeliot\DoctrineEncryptedContracts\EncryptedType abstract class to create a custom encrypted field type:
use Aeliot\DoctrineEncryptedContracts\EncryptedType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class CustomEncryptedStringType extends EncryptedType
{
public function getName(): string
{
return 'custom_encrypted_string';
}
public function getSQLDeclaration(
array $column,
AbstractPlatform $platform
): string {
return $platform->getStringTypeDeclarationSQL($column);
}
}
Register the Type
Add your type to Doctrine’s configuration (e.g., in config/packages/doctrine.yaml):
doctrine:
orm:
mappings:
App:
type: attribute
dir: "%kernel.project_dir%/src/Entity"
prefix: "App\Entity"
is_bundle: false
dbal:
types:
custom_encrypted_string: App\Doctrine\DBAL\Type\CustomEncryptedStringType
Annotate an Entity Field
use Doctrine\ORM\Mapping as ORM;
use Aeliot\DoctrineEncryptedContracts\Attributes as Encrypted;
#[ORM\Entity]
class User
{
#[ORM\Column(type: 'custom_encrypted_string')]
#[Encrypted\Encrypted]
private string $sensitiveData;
}
Encrypted Field Creation
EncryptedType for custom logic (e.g., key derivation, cipher selection).convertToDatabaseValue() and convertToPHPValue() for serialization/deserialization.Integration with doctrine-encrypted-bundle
EncryptedField trait in entities to auto-apply encryption:
use Aeliot\DoctrineEncryptedContracts\Traits\EncryptedField;
#[ORM\Entity]
class User
{
use EncryptedField;
#[ORM\Column(type: 'string')]
#[Encrypted\Encrypted]
private string $password;
}
Query Filtering
EncryptedType::getComparisonExpression() to build encrypted queries:
$qb = $entityManager->createQueryBuilder();
$qb->andWhere('u.sensitiveData = :value')
->setParameter('value', $encryptedValue);
Bulk Operations
EntityManager::createNativeQuery() with raw SQL for bulk inserts/updates of encrypted fields.php bin/console make:migration
php bin/console doctrine:migrations:migrate
Key Rotation
Indexing Limitations
Type Safety
getSQLDeclaration() returns a compatible DBAL type (e.g., VARCHAR for strings). Mismatches cause ClassNotFoundException.Serialization Conflicts
__serialize()/__unserialize() or @ORM\Transient for non-persistent properties.doctrine:
dbal:
logging: true
convertToPHPValue() to log decrypted values for debugging:
public function convertToPHPValue($value, AbstractPlatform $platform)
{
error_log("Decrypted: " . print_r($value, true));
return parent::convertToPHPValue($value, $platform);
}
Custom Ciphers
Aeliot\DoctrineEncryptedContracts\Contracts\CipherInterface for non-standard encryption (e.g., RSA-OAEP):
class RsaCipher implements CipherInterface
{
public function encrypt(string $data, string $key): string { ... }
public function decrypt(string $data, string $key): string { ... }
}
Field-Level Config
#[Encrypted\Encrypted(
cipher: 'AesCbc',
key: 'custom_key_123',
algorithm: 'aes-256-cbc'
)]
private string $customField;
Event Listeners
prePersist/preUpdate for dynamic key resolution:
$entityManager->getEventManager()->addEventListener(
[User::class],
new EncryptedFieldListener($keyProvider)
);
How can I help you explore Laravel packages today?