'', 'number' => 0, 'color' => '#000000', 'image' => '', 'boolean' => false, 'select' => '', 'list' => [], ]; /** @return array */ public static function params_of($cmp): array { $p = Value::get($cmp, 'props'); return Value::isObjectish($p) ? $p : []; } public static function has_params($cmp): bool { return self::params_of($cmp) !== []; } /** @return array The value of every declared parameter. */ public static function resolve_values($schema, $values): array { $props = self::params_of($schema); $out = []; foreach ($props as $key => $def) { $out[$key] = self::coerce($def, Value::get($values, (string) $key)); } return $out; } /** @return array The custom properties the instance's values set. */ public static function css_vars_of($schema, $values): array { $out = []; foreach (self::params_of($schema) as $key => $def) { $css = Value::get($def, 'css'); if (!$css) { continue; } $v = Value::get($values, (string) $key); if ($v === null || $v === '') { continue; } $unit = Value::get($def, 'unit'); $out[$css] = (Value::get($def, 'type') === 'number' && $unit) ? Value::str($v) . $unit : Value::str($v); } return $out; } private static function default_of($def) { if (is_array($def) && array_key_exists('default', $def)) { return $def['default']; } $type = Value::get($def, 'type'); if ($type === 'list') { return []; } if ($type === 'select') { $options = Value::get($def, 'options'); $first = (is_array($options) && isset($options[0])) ? Value::get($options[0], 'value') : null; return $first ?? ''; } return self::FALLBACK[$type] ?? null; } private static function coerce($def, $raw) { if ($raw === null) { return self::default_of($def); } switch (Value::get($def, 'type')) { case 'number': $n = (is_int($raw) || is_float($raw)) ? $raw : (float) $raw; if (!is_finite((float) $n)) { return self::default_of($def); } $min = Value::get($def, 'min'); $max = Value::get($def, 'max'); if ($min !== null) { $n = max($min, $n); } if ($max !== null) { $n = min($max, $n); } return $n; case 'boolean': return (bool) $raw; case 'select': $options = Value::get($def, 'options'); $options = is_array($options) ? $options : []; foreach ($options as $o) { if (Value::get($o, 'value') === $raw) { return $raw; } } return self::default_of($def); case 'list': if (!is_array($raw) || !Value::isList($raw)) { return self::default_of($def); } $of = Value::isObjectish(Value::get($def, 'of')) ? $def['of'] : []; $items = []; foreach ($raw as $raw2) { $item = Value::isObjectish($raw2) ? $raw2 : []; $o = []; foreach ($item as $k => $v) { if (!array_key_exists($k, $of)) { $o[$k] = $v; } } foreach ($of as $k => $d) { $o[$k] = self::coerce($d, Value::get($item, (string) $k)); } $items[] = $o; } $max = Value::get($def, 'max'); return $max !== null ? array_slice($items, 0, (int) $max) : $items; default: return is_string($raw) ? $raw : Value::str($raw); } } }