Annotations

Flexagon reads PHPDoc tags at runtime to modify behavior (PhpDocUtil).

The canonical notation is snake_case.

/** @encrypt */
/** @db_auto_timestamp insert|update */
/** @exclude_from_get_array */

Tag names are case-insensitive and separator-insensitive. The following forms are equivalent.

@db_auto_timestamp    @DbAutoTimestamp    @DB_AUTO_TIMESTAMP    @dbautotimestamp

Tag values are case-insensitive, but separators remain significant (insert = INSERT, while my_value ≠ myvalue).

Both single-line docblocks (/** @db_auto_timestamp insert */) and multiline docblocks are supported.

@db_auto_timestamp

Automatically fills Unix timestamps on INSERT and UPDATE. This is already applied to createdAt and updatedAt in BaseModel.

/**
 * @var int|null
 * @db_auto_timestamp insert
 */
protected ?int $createdAt = null;

/**
 * @var int|null
 * @db_auto_timestamp insert|update
 */
protected ?int $updatedAt = null;

@encrypt

Automatically encrypts and decrypts properties with AES-256-CBC. Values are encrypted before being stored in the database and decrypted when query results are mapped back to objects.

Ciphertext uses the format base64(version || IV || HMAC-SHA256 || ciphertext). The IV is a synthetic IV derived from the plaintext with a keyed HMAC, so identical plaintext always produces identical ciphertext and an encrypted column can be matched with WHERE col = :COL (in exchange, rows with equal values are recognisable as equal in the database). Before decryption, the HMAC is verified with hash_equals() to reject tampered data. Encryption and authentication keys are derived separately from the passphrase using hash_hkdf().

/**
 * @var string
 * @encrypt
 */
private string $residentNumber = '';

_Global::$CLASS_PROPERTY_ENCRYPTION_PASSPHRASE must be at least 10 characters long or an exception is thrown. Make sure the database column is large enough to hold the ciphertext.

@exclude_from_get_array

Excludes a getter from getArray() / getJson() output. Use it for values such as password hashes that should not be serialized.

/**
 * @exclude_from_get_array
 */
public function getPasswordHash(): string { return $this->passwordHash; }

Calling getArray(forceAll: true) ignores exclusions and returns all values. DAOs use this mode internally when writing to the database.

See ANNOTATIONS.md for the complete list, constraints, and instructions for defining custom annotations.