Refactor token resolution to honor unresolved policy (blank|keep) without exceptions; update renderer and policy test
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Documents;
|
||||
|
||||
use App\Models\Contract;
|
||||
use App\Models\DocumentTemplate;
|
||||
use App\Models\User;
|
||||
|
||||
class TokenValueResolver
|
||||
{
|
||||
/**
|
||||
* Resolve tokens to values.
|
||||
* Returns array with keys: values (resolved token=>value) and unresolved (list of tokens not resolved / not allowed)
|
||||
* Policy determines whether invalid tokens throw (fail) or are collected (blank|keep).
|
||||
*
|
||||
* @return array{values:array<string,string>,unresolved:array<int,string>}
|
||||
*/
|
||||
public function resolve(array $tokens, DocumentTemplate $template, Contract $contract, User $user, string $policy = 'fail'): array
|
||||
{
|
||||
$values = [];
|
||||
$unresolved = [];
|
||||
$globalWhitelist = config('documents.whitelist', []);
|
||||
$templateEntities = $template->entities ?: array_keys($globalWhitelist);
|
||||
foreach ($tokens as $token) {
|
||||
[$entity,$attr] = explode('.', $token, 2);
|
||||
if ($entity === 'generation') {
|
||||
$values[$token] = $this->generationAttribute($attr, $user);
|
||||
|
||||
continue;
|
||||
}
|
||||
if (! in_array($entity, $templateEntities, true)) {
|
||||
if ($policy === 'fail') {
|
||||
throw new \RuntimeException("Nedovoljen entiteta token: $entity");
|
||||
}
|
||||
$unresolved[] = $token;
|
||||
|
||||
continue;
|
||||
}
|
||||
$allowed = ($template->columns[$entity] ?? []) ?: ($globalWhitelist[$entity] ?? []);
|
||||
if (! in_array($attr, $allowed, true)) {
|
||||
if ($policy === 'fail') {
|
||||
throw new \RuntimeException("Nedovoljen stolpec token: $token");
|
||||
}
|
||||
$unresolved[] = $token;
|
||||
|
||||
continue;
|
||||
}
|
||||
$values[$token] = $this->entityAttribute($entity, $attr, $contract) ?? '';
|
||||
}
|
||||
|
||||
return ['values' => $values, 'unresolved' => array_values(array_unique($unresolved))];
|
||||
}
|
||||
|
||||
private function generationAttribute(string $attr, User $user): string
|
||||
{
|
||||
return match ($attr) {
|
||||
'timestamp' => (string) now()->timestamp,
|
||||
'date' => now()->toDateString(), // raw ISO; formatting applied later
|
||||
'user_name' => $user->name ?? 'Uporabnik',
|
||||
default => ''
|
||||
};
|
||||
}
|
||||
|
||||
private function entityAttribute(string $entity, string $attr, Contract $contract): ?string
|
||||
{
|
||||
switch ($entity) {
|
||||
case 'contract':
|
||||
return (string) ($contract->{$attr} ?? '');
|
||||
case 'client_case':
|
||||
return (string) optional($contract->clientCase)->{$attr};
|
||||
case 'client':
|
||||
return (string) optional(optional($contract->clientCase)->client)->{$attr};
|
||||
case 'person':
|
||||
$person = optional(optional($contract->clientCase)->person);
|
||||
|
||||
return (string) $person->{$attr};
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user