'', "ââ¬â¢" => "’", "ââ¬Ë" => "â", "ââ¬Å" => "“", "ââ¬\x9d" => "”", "ââ¬Â" => "”", "â⬓" => "–", "â⬔" => "—", "ââ¬Â¦" => "â¦", "é" => "é", "è" => "è", "ê" => "ê", "á" => "á", "ÃÂ" => "í", "ó" => "ó", "ñ" => "ñ", "café" => "café", "Crème" => "Crème", "crème" => "crème", "BŽ" => "Bé", "CrŽme" => "Crème", "Jalapeño" => "Jalapeño", "Ã" => "", "Ã" => "’", "Ã" => "—", ]; $s = strtr($s, $map); $s = preg_replace_callback('/[\x80-\x9F]/', function($m){ $cp1252 = [ "\x80"=>"â¬","\x82"=>"â","\x83"=>"Æ","\x84"=>"â","\x85"=>"â¦","\x86"=>"â ","\x87"=>"â¡","\x88"=>"Ë","\x89"=>"â°", "\x8A"=>"Å ","\x8B"=>"â¹","\x8C"=>"Å","\x8E"=>"Ž","\x91"=>"â","\x92"=>"’","\x93"=>"“","\x94"=>"”","\x95"=>"•", "\x96"=>"–","\x97"=>"—","\x98"=>"Ë","\x99"=>"â¢","\x9A"=>"Å¡","\x9B"=>"âº","\x9C"=>"Å","\x9E"=>"ž","\x9F"=>"Ÿ" ]; return $cp1252[$m[0]] ?? $m[0]; }, $s); return $s; } function read_csv_assoc(string $file, string $delim = ','): array { if (!is_readable($file)) return []; $out = []; $fh = fopen($file, 'r'); if (!$fh) return []; $header = fgetcsv($fh, 0, $delim); if ($header === false) { fclose($fh); return []; } if (isset($header[0])) $header[0] = preg_replace('/^\xEF\xBB\xBF/', '', (string)$header[0]); $keys = array_map(function($h){ $h = strtolower(trim((string)$h)); $h = preg_replace('/\s+/', '_', $h); $h = preg_replace('/[^a-z0-9_]+/','', $h); return $h; }, $header); while (($row = fgetcsv($fh, 0, $delim)) !== false) { if (count($row) === 1 && trim((string)$row[0]) === '') continue; $assoc = []; foreach ($keys as $i => $k) { $assoc[$k] = bw_fix_text((string)($row[$i] ?? '')); } $out[] = $assoc; } fclose($fh); return $out; } function lesson_week(array $r): string { $w = col($r, 'week'); if ($w !== '') return (string)$w; // fallback: try to extract from slug or source_file (e.g., week-12) $slug = strtolower(col($r,'slug').col($r,'source_file')); if (preg_match('/week[-_\s]?(\d{1,2})/', $slug, $m)) { return $m[1]; } return ''; } /* ---------------- load data ---------------- */ $lessons = read_csv_assoc($CSV_PATH); /* tags universe (for filters) */ $tag_counts = []; foreach ($lessons as $r) { $tags = array_filter(array_map('trim', preg_split('/[;,|]/', (string)($r['tags'] ?? '')))); foreach ($tags as $t) { $tag_counts[$t] = ($tag_counts[$t] ?? 0) + 1; } } arsort($tag_counts); $tags_sorted = array_keys($tag_counts); function col($row, $key, $fallback=''){ return trim((string)($row[$key] ?? $fallback)); } function first_nonempty(...$vals){ foreach($vals as $v){ if (strlen(trim((string)$v))) return $v; } return ''; } function truthy($v): bool { $v = strtolower(trim((string)$v)); return in_array($v, ['1','true','yes','y','on'], true); } function is_featured(array $r): bool { if (truthy(col($r,'featured')) || truthy(col($r,'is_featured')) || truthy(col($r,'homepage'))) return true; $tags = array_map('strtolower', array_filter(array_map('trim', preg_split('/[;,|]/', (string)col($r,'tags'))))); return in_array('featured', $tags, true); } function lesson_url(array $r): string { $slug = trim((string)($r['slug'] ?? '')); if ($slug === '') { $title = (string)($r['title'] ?? 'lesson'); $slug = strtolower(preg_replace('/[^a-z0-9]+/i', '-', $title)); } return "/learn/{$slug}/"; } /* Strip first 2 non-empty lines from description, then clamp (CSS) */ /* Strip first 2 non-empty lines; if empty, fall back to original text or tags */ function lesson_desc(array $r): string { $raw = first_nonempty( col($r,'paragraph_text'), col($r,'description'), col($r,'summary'), col($r,'excerpt'), col($r,'notes'), '' ); $raw = trim($raw); // If nothing in CSV fields, fall back to tags (up to 3) if ($raw === '') { $tags = array_filter(array_map('trim', preg_split('/[;,|]/', (string)col($r,'tags')))); if (!empty($tags)) return implode(' · ', array_slice($tags, 0, 3)); return ' '; // keeps layout stable even if totally empty } // Strip first 2 non-empty lines $lines = preg_split('/\R+/', $raw); $keep = []; $skipped = 0; foreach ($lines as $ln) { $t = trim($ln); if ($t==='') continue; if ($skipped < 2) { $skipped++; continue; } $keep[] = $ln; } $s = trim(implode(' ', $keep === [] ? $lines : $keep)); $s = preg_replace('/\s{2,}/',' ', $s); // If stripping made it empty, fall back to original raw if ($s === '') $s = $raw; return $s; } ?> Master cooking one week at a time. Build skills, gain confidence, and enjoy the journey of learning in your own kitchen. No lessons found. Restore /api/lessons.csv and reload.