| 1 |
<?php |
| 2 |
// process_form.php |
| 3 |
require_once 'functions.php'; |
| 4 |
require_once 'parse_colors.php'; |
| 5 |
|
| 6 |
define('MAX_COLORS', 50); |
| 7 |
|
| 8 |
function processColorForm($colors, $skip_black_white = false) { |
| 9 |
$parsed_colors = []; |
| 10 |
$invalid_colors = []; |
| 11 |
$duplicate_colors = []; |
| 12 |
$semantic_duplicates = []; |
| 13 |
$excess_colors = false; |
| 14 |
|
| 15 |
// Split and clean input |
| 16 |
$cleaned_input = preg_split('/\n/', $colors); |
| 17 |
$cleaned_input = array_map(function($line) { |
| 18 |
return array_filter(preg_split('/;+/', $line), 'strlen'); |
| 19 |
}, $cleaned_input); |
| 20 |
$cleaned_input = array_merge(...$cleaned_input); |
| 21 |
$cleaned_input = array_map('trim', array_filter($cleaned_input, 'strlen')); |
| 22 |
|
| 23 |
// Track unique colors, duplicates, and semantic duplicates |
| 24 |
$seen_colors = []; |
| 25 |
$seen_rgb_values = []; |
| 26 |
$unique_colors = []; |
| 27 |
|
| 28 |
foreach ($cleaned_input as $color) { |
| 29 |
$clean_color = trim(preg_replace(['/\/\*.*?\*\//s', '/\/\/[^;\n]*[;\n]/'], '', $color)); |
| 30 |
if (empty($clean_color)) continue; |
| 31 |
|
| 32 |
$normalized = strtoupper($clean_color); |
| 33 |
$rgb = parseColor($clean_color); |
| 34 |
|
| 35 |
if ($rgb !== false) { |
| 36 |
// Create a normalized RGB string for comparison |
| 37 |
$rgb_key = implode(',', array_slice($rgb, 0, 3)) . ',' . (isset($rgb[3]) ? $rgb[3] : 1); |
| 38 |
|
| 39 |
if (isset($seen_colors[$normalized])) { |
| 40 |
// Exact duplicate (same format) |
| 41 |
if (!in_array($clean_color, $duplicate_colors)) { |
| 42 |
$duplicate_colors[] = $seen_colors[$normalized]; |
| 43 |
} |
| 44 |
} elseif (isset($seen_rgb_values[$rgb_key])) { |
| 45 |
// Semantic duplicate (different format, same color) |
| 46 |
if (!isset($semantic_duplicates[$rgb_key])) { |
| 47 |
$semantic_duplicates[$rgb_key] = [ |
| 48 |
'original' => $seen_rgb_values[$rgb_key], |
| 49 |
'duplicates' => [] |
| 50 |
]; |
| 51 |
} |
| 52 |
$semantic_duplicates[$rgb_key]['duplicates'][] = $clean_color; |
| 53 |
} else { |
| 54 |
$seen_colors[$normalized] = $clean_color; |
| 55 |
$seen_rgb_values[$rgb_key] = $clean_color; |
| 56 |
$unique_colors[] = $color; |
| 57 |
} |
| 58 |
} else { |
| 59 |
$invalid_colors[] = $color; |
| 60 |
} |
| 61 |
} |
| 62 |
|
| 63 |
// Process max colors limit |
| 64 |
if (count($unique_colors) > MAX_COLORS) { |
| 65 |
$excess_colors = true; |
| 66 |
$unique_colors = array_slice($unique_colors, 0, MAX_COLORS); |
| 67 |
} |
| 68 |
|
| 69 |
// Process colors for output |
| 70 |
$has_white = false; |
| 71 |
$has_black = false; |
| 72 |
|
| 73 |
foreach ($unique_colors as $color) { |
| 74 |
$clean_color = trim(preg_replace(['/\/\*.*?\*\//s', '/\/\/[^;\n]*[;\n]/'], '', $color)); |
| 75 |
if (empty($clean_color)) continue; |
| 76 |
|
| 77 |
$rgb = parseColor($clean_color); |
| 78 |
if ($rgb !== false) { |
| 79 |
$parsed_colors[$color] = [ |
| 80 |
'rgb' => array_slice($rgb, 0, 3), |
| 81 |
'alpha' => isset($rgb[3]) ? $rgb[3] : 1, |
| 82 |
'luminance' => getLuminance(array_slice($rgb, 0, 3)) |
| 83 |
]; |
| 84 |
|
| 85 |
// Check if color is white or black |
| 86 |
$rgb_values = array_slice($rgb, 0, 3); |
| 87 |
if ($rgb_values == [255, 255, 255] && (isset($rgb[3]) ? $rgb[3] : 1) == 1) { |
| 88 |
$has_white = true; |
| 89 |
} |
| 90 |
if ($rgb_values == [0, 0, 0] && (isset($rgb[3]) ? $rgb[3] : 1) == 1) { |
| 91 |
$has_black = true; |
| 92 |
} |
| 93 |
} |
| 94 |
} |
| 95 |
|
| 96 |
// Add black and white for single color case, excluding duplicates |
| 97 |
// Skip this in advanced mode to avoid adding black and white for dark/light mode background colors |
| 98 |
if (!$skip_black_white && count($parsed_colors) === 1) { |
| 99 |
if (!$has_black) { |
| 100 |
$parsed_colors['black'] = [ |
| 101 |
'rgb' => [0, 0, 0], |
| 102 |
'alpha' => 1, |
| 103 |
'luminance' => getLuminance([0, 0, 0]) |
| 104 |
]; |
| 105 |
} |
| 106 |
if (!$has_white) { |
| 107 |
$parsed_colors['white'] = [ |
| 108 |
'rgb' => [255, 255, 255], |
| 109 |
'alpha' => 1, |
| 110 |
'luminance' => getLuminance([255, 255, 255]) |
| 111 |
]; |
| 112 |
} |
| 113 |
} |
| 114 |
|
| 115 |
return [ |
| 116 |
'parsed_colors' => $parsed_colors, |
| 117 |
'invalid_colors' => $invalid_colors, |
| 118 |
'duplicate_colors' => $duplicate_colors, |
| 119 |
'semantic_duplicates' => $semantic_duplicates, |
| 120 |
'excess_colors' => $excess_colors, |
| 121 |
'original_input' => $unique_colors |
| 122 |
]; |
| 123 |
} |
| 124 |
|
| 125 |
function processAdvancedModeColors($light_text, $light_primary, $light_bg, $dark_text, $dark_primary, $dark_bg) { |
| 126 |
// Helper function to parse multiple colors from textarea input |
| 127 |
$parseColorField = function($input) { |
| 128 |
if (empty(trim($input))) { |
| 129 |
return ['colors' => [], 'invalid' => []]; |
| 130 |
} |
| 131 |
$colors = []; |
| 132 |
$invalid = []; |
| 133 |
$lines = preg_split('/\r\n|\r|\n/', trim($input)); |
| 134 |
foreach ($lines as $line) { |
| 135 |
$line = trim($line); |
| 136 |
if (empty($line)) continue; |
| 137 |
$rgb = parseColor($line); |
| 138 |
if ($rgb !== false) { |
| 139 |
$colors[] = $line; |
| 140 |
} else { |
| 141 |
$invalid[] = $line; |
| 142 |
} |
| 143 |
} |
| 144 |
return ['colors' => $colors, 'invalid' => $invalid]; |
| 145 |
}; |
| 146 |
|
| 147 |
// Collect light mode background colors |
| 148 |
$light_bg_result = $parseColorField($light_bg); |
| 149 |
$light_bg_colors = $light_bg_result['colors']; |
| 150 |
$light_bg_invalid = $light_bg_result['invalid']; |
| 151 |
|
| 152 |
// Collect light mode foreground colors (text + primary + always include black and white) |
| 153 |
$light_text_result = $parseColorField($light_text); |
| 154 |
$light_primary_result = $parseColorField($light_primary); |
| 155 |
$light_fg_colors = array_merge($light_text_result['colors'], $light_primary_result['colors'], ['#FFFFFF', '#000000']); |
| 156 |
$light_fg_invalid = array_merge($light_text_result['invalid'], $light_primary_result['invalid']); |
| 157 |
|
| 158 |
// Add primary colors to background colors (primary colors function as both foreground and background) |
| 159 |
$light_bg_colors = array_merge($light_bg_colors, $light_primary_result['colors']); |
| 160 |
|
| 161 |
// Collect dark mode background colors |
| 162 |
$dark_bg_result = $parseColorField($dark_bg); |
| 163 |
$dark_bg_colors = $dark_bg_result['colors']; |
| 164 |
$dark_bg_invalid = $dark_bg_result['invalid']; |
| 165 |
|
| 166 |
// Collect dark mode foreground colors (text + primary + always include black and white) |
| 167 |
$dark_text_result = $parseColorField($dark_text); |
| 168 |
$dark_primary_result = $parseColorField($dark_primary); |
| 169 |
$dark_fg_colors = array_merge($dark_text_result['colors'], $dark_primary_result['colors'], ['#FFFFFF', '#000000']); |
| 170 |
$dark_fg_invalid = array_merge($dark_text_result['invalid'], $dark_primary_result['invalid']); |
| 171 |
|
| 172 |
// Add primary colors to background colors (primary colors function as both foreground and background) |
| 173 |
$dark_bg_colors = array_merge($dark_bg_colors, $dark_primary_result['colors']); |
| 174 |
|
| 175 |
// Process light mode background colors |
| 176 |
$light_bg_result = processColorForm(implode("\n", $light_bg_colors), true); |
| 177 |
|
| 178 |
// Process light mode foreground colors |
| 179 |
$light_fg_result = processColorForm(implode("\n", $light_fg_colors), true); |
| 180 |
|
| 181 |
// Process dark mode background colors |
| 182 |
$dark_bg_result = processColorForm(implode("\n", $dark_bg_colors), true); |
| 183 |
|
| 184 |
// Process dark mode foreground colors |
| 185 |
$dark_fg_result = processColorForm(implode("\n", $dark_fg_colors), true); |
| 186 |
|
| 187 |
return [ |
| 188 |
'light_mode' => [ |
| 189 |
'background_colors' => $light_bg_result['parsed_colors'], |
| 190 |
'foreground_colors' => $light_fg_result['parsed_colors'], |
| 191 |
'invalid_colors' => array_merge($light_bg_result['invalid_colors'], $light_fg_result['invalid_colors'], $light_bg_invalid, $light_fg_invalid), |
| 192 |
'duplicate_colors' => array_merge($light_bg_result['duplicate_colors'], $light_fg_result['duplicate_colors']), |
| 193 |
'semantic_duplicates' => array_merge($light_bg_result['semantic_duplicates'], $light_fg_result['semantic_duplicates']), |
| 194 |
'excess_colors' => $light_bg_result['excess_colors'] || $light_fg_result['excess_colors'] |
| 195 |
], |
| 196 |
'dark_mode' => [ |
| 197 |
'background_colors' => $dark_bg_result['parsed_colors'], |
| 198 |
'foreground_colors' => $dark_fg_result['parsed_colors'], |
| 199 |
'invalid_colors' => array_merge($dark_bg_result['invalid_colors'], $dark_fg_result['invalid_colors'], $dark_bg_invalid, $dark_fg_invalid), |
| 200 |
'duplicate_colors' => array_merge($dark_bg_result['duplicate_colors'], $dark_fg_result['duplicate_colors']), |
| 201 |
'semantic_duplicates' => array_merge($dark_bg_result['semantic_duplicates'], $dark_fg_result['semantic_duplicates']), |
| 202 |
'excess_colors' => $dark_bg_result['excess_colors'] || $dark_fg_result['excess_colors'] |
| 203 |
] |
| 204 |
]; |
| 205 |
} |
| 206 |
?> |