kithkin/app/Support/helpers.php

154 lines
4.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
if (! function_exists('format_event_url')) {
/**
* format an event url with a given calendar ID and event ID
*/
function format_event_url(string $eid, string $cid): string
{
return 'calendar/'.$cid.'/event/'.$eid;
}
}
if (! function_exists('contrast_text_color')) {
/**
* Choose an accessible foreground (#fff or #000) against a HEX background.
*
* Rule set:
* 1. Calculate WCAG contrast ratios for both black and white.
* 2. Prefer the colour with the *higher* ratio.
* 3. Override: if black wins but ratio < 5.5 AND white > 4, use white.
*
* @param string $hex Background colour (3- or 6-digit hex, with or without #)
* @param string $light Return value for “white” (default '#ffffff')
* @param string $dark Return value for “black” (default '#000000')
* @return string
*/
function contrast_text_color(string $hex, string $light = '#ffffff', string $dark = '#000000'): string
{
// --- normalise ----------------------------------------------------
$hex = ltrim($hex, '#');
if (strlen($hex) === 3) { // #abc → #aabbcc
$hex = preg_replace('/./', '$0$0', $hex);
}
[$r, $g, $b] = [
hexdec(substr($hex, 0, 2)) / 255,
hexdec(substr($hex, 2, 2)) / 255,
hexdec(substr($hex, 4, 2)) / 255,
];
// --- convert sRGB → linear RGB -----------------------------------
$linear = function (float $c): float {
return $c <= 0.04045 ? $c / 12.92 : pow(($c + 0.055) / 1.055, 2.4);
};
$R = $linear($r);
$G = $linear($g);
$B = $linear($b);
// --- relative luminance (ITU-R BT.709) ----------------------------
$L_bg = 0.2126 * $R + 0.7152 * $G + 0.0722 * $B; // 01
// --- contrast ratios vs black (L=0) and white (L=1) ---------------
$contrast_black = ($L_bg + 0.05) / 0.05; // bg lighter than black
$contrast_white = 1.05 / ($L_bg + 0.05); // white vs bg
// --- pick the winner ---------------------------------------------
$useDark = $contrast_black >= $contrast_white;
// override rule if dark is true but white "looks better"
if ($useDark && $contrast_black < 5.5 && $contrast_white > 4) {
$useDark = false; // switch to white
}
return $useDark ? $dark : $light;
}
}
if (! function_exists('is_hex_color')) {
function is_hex_color(mixed $value): bool
{
return is_string($value) && preg_match('/^#[0-9A-Fa-f]{6}$/', $value) === 1;
}
}
if (! function_exists('calendar_color_palette')) {
/**
* returns a cleaned palette from config (valid hex only).
*
* @return array<int,string>
*/
function calendar_color_palette(): array
{
$palette = config('kithkin.calendar.color_palette', []);
if (! is_array($palette)) {
$palette = [];
}
return array_values(array_filter($palette, fn ($c) => is_hex_color($c)));
}
}
if (! function_exists('calendar_color_failsafe')) {
function calendar_color_failsafe(): string
{
$fallback = config('kithkin.calendar.color_failsafe', '#1a1a1a');
return is_hex_color($fallback) ? $fallback : '#1a1a1a';
}
}
if (! function_exists('default_calendar_color')) {
/**
* returns the default calendar color from the configured palette.
* if the palette is empty/invalid, falls back to the failsafe.
*/
function default_calendar_color(): string
{
$palette = calendar_color_palette();
if (count($palette) === 0) {
return calendar_color_failsafe();
}
$strategy = config('kithkin.calendar.default_color_strategy', 'first');
if ($strategy === 'random') {
return $palette[array_rand($palette)];
}
return $palette[0];
}
}
if (! function_exists('calendar_color')) {
/**
* pick a calendar color with a single source of truth for defaults.
*
* order:
* 1) $data['color'] if valid
* 2) $fallback if valid
* 3) default_calendar_color() (palette-based)
* 4) hard failsafe from config, then '#1a1a1a'
*
* @param array<string,mixed> $data
*/
function calendar_color(array $data = [], ?string $fallback = null): string
{
$raw = $data['color'] ?? null;
if (is_hex_color($raw)) {
return $raw;
}
if (is_hex_color($fallback)) {
return $fallback;
}
$default = default_calendar_color();
return is_hex_color($default) ? $default : calendar_color_failsafe();
}
}