Pular para o conteúdo principal

← Configuração · Voltar ao README · Referência da API →

Conversões de payload

Valores JSON padrão​

Sem uma conversão personalizada, o pacote codifica cada valor como JSON durante a escrita e retorna o valor JSON decodificado exato durante a leitura. Isso inclui null, strings vazias, strings de espaços, arrays vazios, zero e false.

$user->settings()->set('notifications', [
'email' => true,
'push' => false,
]);

$notifications = $user->settings()->get('notifications');

Os valores devem ser serializáveis em JSON. Erros de codificação JSON não são suprimidos.

Seleção da conversão​

O formato legado para todo o modelo aplica uma conversão a todas as configurações pertencentes a uma classe de modelo pai:

'casts' => [
App\Models\User::class => App\Casts\UserSettingsPayloadCast::class,
],

Use um mapa por chave quando somente chaves exatas precisarem de tratamento personalizado:

'casts' => [
App\Models\User::class => [
'profile' => App\Data\ProfileData::class,
'billing.credentials' => App\Casts\EncryptedSettingPayload::class,
],
],

Os aliases do morph map do Laravel são resolvidos de volta para a classe do modelo pai antes da seleção. A correspondência usa a chave armazenada da configuração, não o nome do atributo Eloquent payload. Pontos são literais, então billing.credentials é uma única chave. Chaves ausentes de um mapa por chave usam o JSON normal.

Uma classe configurada deve implementar CastsAttributes ou estender Spatie\LaravelData\Data. Classes configuradas inválidas, ausentes, incompatíveis ou que o container não consegue resolver lançam InvalidPayloadCast; o pacote não volta silenciosamente ao JSON simples para uma entrada configurada.

Ciclo de vida da conversão​

Para uma implementação de CastsAttributes, o pacote executa esta sequência:

DireçãoSequência
EscritaChamar o set() personalizado e codificar o resultado como JSON
LeituraPassar a string JSON armazenada para o get() personalizado

O argumento $model é o modelo de armazenamento configurado, não o modelo pai User ou Post. O pacote resolve implementações de CastsAttributes pelo container do Laravel, então dependências do construtor podem usar os bindings normais do container. Conversões personalizadas de set() recebem todos os valores de entrada, incluindo valores que o Laravel considera vazios.

Conversão de atributo do Eloquent​

A conversão pode implementar o contrato CastsAttributes do Laravel:

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

final class UserSettingsPayloadCast implements CastsAttributes
{
public function get(Model $model, string $key, mixed $value, array $attributes): array
{
return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
}

public function set(Model $model, string $key, mixed $value, array $attributes): array
{
return (array) $value;
}
}

O resultado do set() personalizado deve continuar serializável em JSON. Erros de codificação JSON não são suprimidos.

Criptografia por chave​

A criptografia pertence a uma conversão da aplicação porque o esquema do pacote não tem metadados de criptografia nem um contrato de rotação de chaves. Esta conversão criptografa uma chave de configuração e mantém todas as outras no caminho JSON normal:

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Casts\Json;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Crypt;

final class EncryptedSettingPayload implements CastsAttributes
{
public function get(Model $model, string $key, mixed $value, array $attributes): mixed
{
$ciphertext = Json::decode($value);

return Json::decode(Crypt::decryptString((string) $ciphertext));
}

public function set(Model $model, string $key, mixed $value, array $attributes): string
{
return Crypt::encryptString(Json::encode($value));
}
}

Registre-a para uma chave literal exata:

'casts' => [
App\Models\User::class => [
'billing.credentials' => App\Casts\EncryptedSettingPayload::class,
],
],
$user->settings()->set('billing.credentials', $credentials);

$credentials = $user->settings()->get('billing.credentials');

Não registre o valor em log antes nem depois da conversão. Se as chaves de criptografia puderem mudar, defina e teste uma política de rotação no nível da aplicação antes de armazenar dados de produção. Não adicione colunas de metadados à tabela do pacote sem um contrato de armazenamento separado que defina versionamento e rotação.

Spatie Laravel Data​

Quando spatie/laravel-data estiver instalado, uma classe Data poderá ser usada diretamente:

composer require spatie/laravel-data:^4.23
'casts' => [
App\Models\User::class => [
'preferences' => App\Data\UserSettingsData::class,
],
],

Passe para set() dados aceitos pela classe ou uma instância de Data. get() retorna uma instância de dados, e all() retorna uma coleção contendo instâncias de dados.

$preferences = UserSettingsData::from([
'timezone' => 'Europe/Paris',
'notifications' => true,
]);

$user->settings()->set('preferences', $preferences);

$preferences = $user->settings()->get('preferences');

Outras chaves do mesmo modelo continuam usando o JSON normal. Use o formato legado para todo o modelo somente quando cada payload desse modelo pai for uma entrada válida para a classe de dados configurada.

Erros de conversão​

DragonCode\LaravelModelSettings\Exceptions\InvalidPayloadCast identifica a classe do modelo pai, a chave da configuração e a conversão configurada quando a resolução falha. Ele nunca inclui o payload. A exceção é lançada em escritas simples e em lote, e também em leituras de valores persistidos que usam essa entrada configurada.

Veja também​