87 lines
2.4 KiB
PHP
87 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Koperasi;
|
|
|
|
use App\Models\Koperasi\PengurusKoperasi;
|
|
use BackedEnum;
|
|
use Illuminate\Support\Collection;
|
|
|
|
abstract class KoperasiSurveyService
|
|
{
|
|
abstract public function dependencies(): array;
|
|
|
|
public function context(?PengurusKoperasi $model): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function requiredFields(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
protected function arrayFields(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function values(mixed $value): array
|
|
{
|
|
if ($value instanceof Collection) {
|
|
$value = $value->all();
|
|
} elseif (is_string($value)) {
|
|
$decoded = json_decode($value, true);
|
|
$value = is_array($decoded) ? $decoded : [$value];
|
|
}
|
|
$values = array_map(fn ($item) => $item instanceof BackedEnum ? $item->value : $item, is_array($value) ? $value : [$value]);
|
|
|
|
return array_values(array_filter($values, fn ($item) => is_string($item) && $item !== ''));
|
|
}
|
|
|
|
protected function matches(array $condition, array $data, array $context): bool
|
|
{
|
|
if (isset($condition['any'])) {
|
|
foreach ($condition['any'] as $option) {
|
|
if ($this->matches($option, $data, $context)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
$parent = $condition['field'];
|
|
if ($condition['source'] === 'profile') {
|
|
$selected = $this->values($context[$parent] ?? null);
|
|
} else {
|
|
if (! $this->active($parent, $data, $context)) {
|
|
return false;
|
|
}
|
|
$selected = $this->values($data[$parent] ?? null);
|
|
}
|
|
|
|
return (bool) array_intersect($selected, $condition['values']);
|
|
}
|
|
|
|
public function active(string $field, array $data, array $context): bool
|
|
{
|
|
foreach ($this->dependencies()[$field] ?? [] as $condition) {
|
|
if (! $this->matches($condition, $data, $context)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function normalize(array $data, array $context): array
|
|
{
|
|
foreach (array_keys($this->dependencies()) as $field) {
|
|
if (! $this->active($field, $data, $context)) {
|
|
$data[$field] = in_array($field, $this->arrayFields(), true) ? [] : null;
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
}
|