ob_start(); // Performance: Signal to footer.php that we lazy-load 3rd party scripts on this page $GLOBALS['lazy_load_3rd_party'] = true; // =================================================================== // ### BEST PRACTICES: Sikkerhedsheaders ### // =================================================================== header("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload"); header("X-Content-Type-Options: nosniff"); header("X-Frame-Options: SAMEORIGIN"); header("Referrer-Policy: strict-origin-when-cross-origin"); header("Permissions-Policy: camera=(), microphone=(), geolocation=()"); header("Cross-Origin-Opener-Policy: same-origin-allow-popups"); // =================================================================== // ### GLOBAL ERROR HANDLER - Redirect til 404 ved kritiske fejl ### // =================================================================== // Tolerant error handler: Logger warnings/notices, redirecter KUN ved fatale fejl set_error_handler(function($severity, $message, $file, $line) { // Ignorer undertrykte fejl (@) if (!(error_reporting() & $severity)) { return false; } // Log alle fejl til error_log for debugging error_log("Stock.php Error [{$severity}]: $message in $file on line $line"); // Kun redirect ved alvorlige fejl (E_ERROR, E_USER_ERROR) // Warnings og notices logges men siden fortsætter if (in_array($severity, [E_ERROR, E_USER_ERROR])) { header("HTTP/1.1 404 Not Found"); header("Location: /404.php"); exit(); } // Returner true for at forhindre PHP's standard error handler return true; }); // Fang fatale fejl (Division by zero, etc.) register_shutdown_function(function() { $error = error_get_last(); if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) { // Log fejlen error_log("Stock.php Fatal Error: " . $error['message'] . " in " . $error['file'] . " on line " . $error['line']); // Redirect til 404 (hvis headers ikke allerede er sendt) if (!headers_sent()) { header("HTTP/1.1 404 Not Found"); header("Location: /404.php"); } exit(); } }); // Fang uncaught exceptions set_exception_handler(function($exception) { error_log("Stock.php Exception: " . $exception->getMessage()); header("HTTP/1.1 404 Not Found"); header("Location: /404.php"); exit(); }); // =// =================================================================== // Din eksisterende kode starter her... // =================================================================== require_once($_SERVER["DOCUMENT_ROOT"] . '/includes/main.php'); // Danske månedsnavne (bruges til datoformatering) $danish_months = ['januar', 'februar', 'marts', 'april', 'maj', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'december']; function clean_company_name($name) { $remove_patterns = [ // Aktieklasser '/\s*Class\s+[A-Z]\s*(Common\s*)?(Stock|Shares?)?/i', '/\s*Ordinary\s+Shares?/i', '/\s*Common\s+Stock/i', '/\s*Preferred\s+Stock/i', // Juridiske suffixer (International) '/\s*,?\s*Inc\.?$/i', '/\s*,?\s*Corp\.?$/i', '/\s*,?\s*Corporation$/i', '/\s*,?\s*Ltd\.?$/i', '/\s*,?\s*Limited$/i', '/\s*,?\s*LLC$/i', '/\s*,?\s*PLC$/i', '/\s*,?\s*S\.?A\.?$/i', '/\s*,?\s*N\.?V\.?$/i', '/\s*,?\s*Co\.?$/i', '/\s*,?\s*Company$/i', '/\s*,?\s*Group$/i', '/\s*,?\s*Holdings?$/i', // Nordiske juridiske suffixer '/\s*\(publ\)\.?$/i', '/\s*publ\.?$/i', '/\s*AB$/i', '/\s*ASA$/i', '/\s*Oyj$/i', '/\s*A\/S$/i', '/\s*ApS$/i', '/\s*HF$/i', '/\s*AG$/i', '/\s*SE$/i', // ADR/ADS '/\s*\(?ADR\)?$/i', '/\s*\(?ADS\)?$/i', '/\s*American\s+Depositary\s+(Shares?|Receipts?)/i', ]; $cleaned = $name; foreach ($remove_patterns as $pattern) { $cleaned = preg_replace($pattern, '', $cleaned); } return trim(preg_replace('/\s+/', ' ', $cleaned)); } function generate_seo_title($company_name, $ticker, $dividend_yield = 0, $max_length = 70, $extra = []) { $clean_name = clean_company_name($company_name); $year = date("Y"); $is_idx = $extra['is_index'] ?? false; $is_cry = $extra['is_crypto'] ?? false; // V2: 'Aktie' flyttet fra suffix til hook – frigør ~6 tegn til '2026' i alle varianter $suffix = " | {$clean_name} ({$ticker})"; $type_label = $is_cry ? 'Krypto' : ($is_idx ? 'Indeks' : 'Aktie'); $analysis_lbl = $is_cry ? 'kryptoanalyse' : ($is_idx ? 'indeksanalyse' : 'aktieanalyse'); // Hent og formater data $rsi = $extra["rsi"] ?? null; $target = $extra["target"] ?? 0; $current_close = $extra["current_close"] ?? 0; $macd = $extra["macd"] ?? null; $macd_signal = $extra["macd_signal"] ?? null; $upside_pct = ($target > 0 && $current_close > 0) ? (($target - $current_close) / $current_close) * 100 : 0; $div_tag = ($dividend_yield > 0) ? number_format($dividend_yield, 1) . "%" : ""; // Hent trend-data $ta_sig = $extra['ta_signal'] ?? null; $ta_sig_en = $extra['ta_signal_en'] ?? null; $in_uptrend = $extra['is_uptrend'] ?? false; $in_downtrend = $extra['is_downtrend'] ?? false; $macd5 = $extra['macd5'] ?? null; $macd5_signal = $extra['macd5_signal'] ?? null; $daily_bull = ($macd !== null && $macd_signal !== null && $macd > $macd_signal); $weekly_bull = ($macd5 !== null && $macd5_signal !== null && $macd5 > $macd5_signal); // Prioriteret hook-logik – KURSMÅL-FIRST baseret på søgeordsanalyse: // 1. Kursmål + upside% (højest søgevolumen) // 2. Udbytte + årstal (høj volumen, stor mulighed) // 3. Trend-signaler (lavere volumen men høj CTR) // 4. RSI (kun i kontekst) // // Stabilitet: vi runder upside/downside til nærmeste 5% så små daglige // kursudsving (fx 32.3% → 32.5%) ikke regenererer titlen hver dag. Det // lader Google akkumulere CTR-data pr title-variant, og reducerer // title-churn som Search Console-støj. $_bucket5 = function($v) { return (int)(round($v / 5) * 5); }; $upside_b = $_bucket5($upside_pct); $downside_b = $_bucket5(abs($upside_pct)); $div_b = (round($dividend_yield * 2) / 2); // nærmeste 0.5% $div_tag_stable = ($dividend_yield > 0) ? number_format($div_b, 1) . "%" : ""; $analyst_total = intval($extra['analyst_total'] ?? 0); $consensus_label = $extra['consensus_label'] ?? ''; $has_consensus = ($analyst_total > 0 && $consensus_label !== ''); // Ændringer baseret på Search Console data: // - "udbytte 2026" threshold sænket fra >5% til >3% (13-20% CTR på pattern) // - "anbefaling" keyword tilføjet til flere hooks (20% CTR på "X aktie anbefaling") // - Ny analytiker-konsensus-hook når vi har Rating-data (selv uden target) // - Tekniske signal-hooks får "+ kursmål" når target > 0 (fanger også kursmål-queries) $hook = ""; // P1: Kursmål med kæmpe upside (>40%) – TOPPRIORITET for søgevolumen if (!$is_idx && $upside_pct > 40 && $target > 0) { $hook = "{$clean_name} kursmål {$year}: {$upside_b}% potentiale – anbefaling og analyse"; // P2: Kursmål med god upside (>15%) – matcher "X kursmål 2026" queries } elseif (!$is_idx && $upside_pct > 15 && $target > 0) { $hook = "{$clean_name} kursmål {$year}: {$upside_b}% potentiale – anbefaling og {$analysis_lbl}"; // P3: Kursmål med downside – matcher "er X overvurderet"-intent } elseif (!$is_idx && $upside_pct < -15 && $target > 0) { $hook = "{$clean_name} kursmål {$year}: {$downside_b}% negativt potentiale – overvurderet?"; // P4: Solidt udbytte (>3%) – udbytte-first title. Data viser 13-20% CTR // på "X udbytte 2026"-queries ned til 3-4% yield, så tærsklen er sænket. } elseif (!$is_idx && $dividend_yield > 3) { $hook = "{$clean_name} udbytte {$year}: {$div_tag_stable} – kursmål og anbefaling"; // P5: Kursmål med moderat upside + udbytte kombineret } elseif (!$is_idx && $target > 0 && $dividend_yield > 2) { $hook = "{$clean_name} kursmål {$year}: {$upside_b}% potentiale + {$div_tag_stable} udbytte"; // P6: Kursmål generisk (har kursmål men lav upside) } elseif (!$is_idx && $target > 0) { $hook = "{$clean_name} kursmål {$year}: {$upside_b}% potentiale – anbefaling og {$analysis_lbl}"; // P7: Moderat udbytte (>2%) uden kursmål } elseif (!$is_idx && $dividend_yield > 2) { $hook = "{$clean_name} udbytte {$year}: {$div_tag_stable} – anbefaling og {$analysis_lbl}"; // P7b: NY – Analytiker-konsensus uden kursmål (f.eks. aktier hvor target mangler // men analytikere har givet anbefaling). Fanger "X aktie anbefaling"-query (20% CTR). } elseif (!$is_idx && $has_consensus) { $hook = "{$clean_name} {$type_label} anbefaling {$year}: {$consensus_label} – {$analysis_lbl}"; // P8: Stærkt Køb signal (optrend + begge MACD positive) } elseif ($ta_sig_en === 'strong_buy') { $hook = "{$clean_name} {$type_label}: Stærkt Køb – anbefaling og analyse {$year}"; // P9: Stærkt Sælg signal } elseif ($ta_sig_en === 'strong_sell') { $hook = "{$clean_name} {$type_label}: Stærkt Sælg – anbefaling og analyse {$year}"; // P10: Købssignal } elseif ($ta_sig_en === 'buy') { $hook = "{$clean_name} {$type_label}: Købssignal – anbefaling og analyse {$year}"; // P11: Salgssignal } elseif ($ta_sig_en === 'sell') { $hook = "{$clean_name} {$type_label}: Salgssignal – anbefaling og analyse {$year}"; // P12: Afvent/blandet } elseif ($ta_sig_en === 'hold') { $hook = "{$clean_name} {$type_label}: Blandet signal – anbefaling og analyse {$year}"; // P13: Udbytte lavt men eksisterende } elseif (!$is_idx && $dividend_yield > 0) { $hook = "{$clean_name} udbytte {$year}: {$div_tag_stable} – anbefaling og {$analysis_lbl}"; // P14: Fallback – inkluder "kursmål" og "anbefaling" for at fange generic long-tail } else { if ($is_idx) { $hook = "{$clean_name} {$type_label}: Kurs og analyse {$year}"; } else { $hook = "{$clean_name} {$type_label} {$year}: kurs, analyse og anbefaling"; } } // Byg og afkort titel $title = $hook . $suffix; if (mb_strlen($title) > $max_length) { // Prøv først uden suffix (hook alene er stadig SEO-stærk) if (mb_strlen($hook) <= $max_length) { $title = $hook; } else { $available_len = $max_length - 3; $title = mb_substr($hook, 0, $available_len) . "..."; } } return $title; } // =================================================================== // DYNAMISK H1-OVERSKRIFT – supplerer title-tag med unik, engagerende overskrift // =================================================================== function generate_h1_title($company_name, $ticker, $dividend_yield = 0, $extra = []) { $clean_name = clean_company_name($company_name); $year = date("Y"); $is_idx = $extra['is_index'] ?? false; $is_cry = $extra['is_crypto'] ?? false; $analysis_label = $is_cry ? 'Kryptoanalyse' : ($is_idx ? 'Indeksanalyse' : 'Aktieanalyse'); $rsi = $extra["rsi"] ?? null; $target = $extra["target"] ?? 0; $current_close = $extra["current_close"] ?? 0; $macd = $extra["macd"] ?? null; $macd_signal = $extra["macd_signal"] ?? null; $upside_pct = ($target > 0 && $current_close > 0) ? (($target - $current_close) / $current_close) * 100 : 0; // Hent trend-data $ta_sig_en = $extra['ta_signal_en'] ?? null; $in_uptrend = $extra['is_uptrend'] ?? false; $in_downtrend = $extra['is_downtrend'] ?? false; $h1 = ""; // Stabiliser upside/downside og udbytte til nærmeste 5% / 0.5% så H1 ikke // muterer dagligt ved små kursudsving – samme logik som i title-funktionen. $upside_b = (int)(round($upside_pct / 5) * 5); $downside_b = (int)(round(abs($upside_pct) / 5) * 5); $div_b = round($dividend_yield * 2) / 2; $div_tag_stable = ($dividend_yield > 0) ? number_format($div_b, 1) . "%" : ""; $analyst_total = intval($extra['analyst_total'] ?? 0); $consensus_label = $extra['consensus_label'] ?? ''; $has_consensus = ($analyst_total > 0 && $consensus_label !== ''); // KURSMÅL-FIRST H1 logik (matcher SEO title prioritering) med "anbefaling" // keyword tilføjet og udbytte-threshold sænket til 3% baseret på CTR-data. if (!$is_idx && $upside_pct > 40 && $target > 0) { $h1 = "{$clean_name} ({$ticker}) kursmål {$year}: {$upside_b}% potentiale – anbefaling og {$analysis_label}"; } elseif (!$is_idx && $upside_pct > 15 && $target > 0) { $h1 = "{$clean_name} ({$ticker}) kursmål {$year}: {$upside_b}% potentiale – anbefaling og {$analysis_label}"; } elseif (!$is_idx && $upside_pct < -15 && $target > 0) { $h1 = "{$clean_name} ({$ticker}) kursmål {$year}: {$downside_b}% negativt potentiale – overvurderet?"; } elseif (!$is_idx && $dividend_yield > 3) { $h1 = "{$clean_name} ({$ticker}) udbytte {$year}: {$div_tag_stable} – kursmål og anbefaling"; } elseif (!$is_idx && $target > 0 && $dividend_yield > 2) { $h1 = "{$clean_name} ({$ticker}) kursmål {$year}: {$upside_b}% potentiale + {$div_tag_stable} udbytte"; } elseif (!$is_idx && $target > 0) { $h1 = "{$clean_name} ({$ticker}) kursmål og anbefaling {$year}"; } elseif (!$is_idx && $dividend_yield > 2) { $h1 = "{$clean_name} ({$ticker}) udbytte {$year}: {$div_tag_stable} – anbefaling og {$analysis_label}"; } elseif (!$is_idx && $has_consensus) { $h1 = "{$clean_name} ({$ticker}) aktie anbefaling {$year}: {$consensus_label} – {$analysis_label}"; } elseif ($ta_sig_en === 'strong_buy') { $h1 = "{$clean_name} ({$ticker}) – Stærkt Køb: anbefaling og {$analysis_label} {$year}"; } elseif ($ta_sig_en === 'strong_sell') { $h1 = "{$clean_name} ({$ticker}) – Stærkt Sælg: anbefaling og {$analysis_label} {$year}"; } elseif ($ta_sig_en === 'buy') { $h1 = "{$clean_name} ({$ticker}) – Købssignal: anbefaling og {$analysis_label} {$year}"; } elseif ($ta_sig_en === 'sell') { $h1 = "{$clean_name} ({$ticker}) – Salgssignal: anbefaling og {$analysis_label} {$year}"; } elseif ($ta_sig_en === 'hold') { $h1 = "{$clean_name} ({$ticker}) – Blandet signal: anbefaling og {$analysis_label} {$year}"; } elseif (!$is_idx && $dividend_yield > 0) { $h1 = "{$clean_name} ({$ticker}) udbytte {$year}: {$div_tag_stable} – anbefaling og {$analysis_label}"; } else { $h1 = "{$clean_name} ({$ticker}) {$analysis_label} {$year}: kurs, kursmål og anbefaling"; } return $h1; } function generate_seo_description($company_name, $ticker, $target, $rsi, $currency, $max_length = 160, $extra = []) { $clean_name = clean_company_name($company_name); $year = date("Y"); $is_idx = $extra['is_index'] ?? false; $is_cry = $extra['is_crypto'] ?? false; $analysis_label = $is_cry ? 'Kryptoanalyse' : ($is_idx ? 'Indeksanalyse' : 'Aktieanalyse'); // Hent og formater data $current_close = $extra["current_close"] ?? 0; $dividend_yield = $extra["dividend_yield"] ?? 0; $macd = $extra["macd"] ?? null; $macd_signal = $extra["macd_signal"] ?? null; $currency_code = rtrim($currency, "."); // Fix for "Kr.." bug // Byg datapunkter $parts = []; // Prefix med kursmål/udbytte/anbefaling-fokus for bedre CTR på søgeresultater. // Stabiliseret til nærmeste 5% så description ikke churner på små kursudsving. $upside_pct = ($target > 0 && $current_close > 0) ? (($target - $current_close) / $current_close) * 100 : 0; $upside_b = (int)(round($upside_pct / 5) * 5); $analyst_total = intval($extra['analyst_total'] ?? 0); $consensus_label = $extra['consensus_label'] ?? ''; if (!$is_idx && $target > 0 && abs($upside_pct) > 10) { $prefix = "{$clean_name} kursmål {$year}: " . $upside_b . "% potentiale. "; } elseif (!$is_idx && $dividend_yield > 3) { $prefix = "{$clean_name} udbytte {$year}: " . number_format($dividend_yield, 1) . "%. "; } elseif (!$is_idx && $analyst_total > 0 && $consensus_label !== '') { // Fanger "X aktie anbefaling"-queries (20% CTR på Ambu/Coloplast/etc.) $prefix = "{$clean_name} aktie anbefaling {$year}: {$consensus_label}. "; } else { $prefix = "{$clean_name} ({$ticker}) {$analysis_label} {$year}: "; } // 1. Kurs if ($current_close > 0) { $parts[] = "Kurs " . number_format($current_close, 2) . " " . $currency_code; } // 2. Kursmål if ($target > 0) { $upside_str = ""; if ($current_close > 0) { $upside_str = " (" . ($upside_pct >= 0 ? "+" : "") . $upside_b . "% potentiale)"; } $parts[] = "Kursmål " . number_format($target, 2) . $upside_str; } // 3. Udbytte if ($dividend_yield > 0) { $parts[] = "Udbytte " . number_format($dividend_yield, 1) . "%"; } // 4. Anbefaling – analytiker-konsensus (fanger "X anbefaling" queries) if ($analyst_total > 0 && $consensus_label !== '') { $parts[] = "Anbefaling: " . $consensus_label; } // 4. RSI if ($rsi && is_numeric($rsi)) { $rsi_status = ($rsi > 70) ? "overkøbt" : (($rsi < 30) ? "oversolgt" : "neutral"); $parts[] = "RSI " . number_format($rsi, 0) . " (" . $rsi_status . ")"; } // 6. MACD trend (nullinje) if ($macd !== null) { $parts[] = "MACD " . ($macd > 0 ? "positiv (bullish trend)" : "negativ (bearish trend)"); } // Byg description med progressiv afkortning (uden fyldord) $description = $prefix; $first = true; foreach ($parts as $part) { $temp_desc = $description . ($first ? "" : " | ") . $part; if (mb_strlen($temp_desc) <= $max_length) { $description = $temp_desc; $first = false; } else { break; // Stop med at tilføje dele, hvis vi overskrider længden } } return $description; } // =================================================================== //Test of push $active_navigation_item = "stock"; $current_page = "stock"; $page_meta_robots_follow = false; $stock_permalink = htmlspecialchars($_GET['permalink'] ?? '', ENT_QUOTES, 'UTF-8'); $page_canonical_url = 'https://'.site_url().'/stock/' . $stock_permalink; $exchange_permalink = $_GET['exchange_permalink'] ?? ""; $sector_permalink = $_GET['sector_permalink'] ?? ""; $country_code = $_GET['country_code'] ?? ""; $is_crypto = boolval($_GET['is_crypto'] ?? 0); $is_index = boolval($_GET['is_index'] ?? 0); // Fallback: detect indeks fra permalink (f.eks. stoxx.indx, sixv.indx) if (!$is_index && str_ends_with(strtoupper($stock_permalink), '.INDX')) { $is_index = true; } $page_meta_robots_follow = true; // =================================================================== // ### ASSET-TYPE TERMINOLOGI – Tilpas sprog til aktie/krypto/indeks ### // =================================================================== if ($is_crypto) { $asset_type = 'kryptovaluta'; $asset_type_bestemt = 'kryptovalutaen'; $asset_suffix = ''; // "Skal man købe Bitcoin nu?" (IKKE "Bitcoin aktien") $asset_suffix_genitive = ''; // "kursmålet for Bitcoin" $analysis_label = 'Kryptoanalyse'; $type_label = 'Krypto'; $asset_kurser_plural = 'kryptokurser'; $asset_en = 'en kryptovaluta'; } elseif ($is_index) { $asset_type = 'indeks'; $asset_type_bestemt = 'indekset'; $asset_suffix = ''; $asset_suffix_genitive = ''; $analysis_label = 'Indeksanalyse'; $type_label = 'Indeks'; $asset_kurser_plural = 'indekskurser'; $asset_en = 'et indeks'; } else { $asset_type = 'aktie'; $asset_type_bestemt = 'aktien'; $asset_suffix = ' aktien'; // "Skal man købe Novo aktien nu?" $asset_suffix_genitive = ' aktien'; // "kursmålet for Novo aktien" $analysis_label = 'Aktieanalyse'; $type_label = 'Aktie'; $asset_kurser_plural = 'aktiekurser'; $asset_en = 'en aktie'; } // =================================================================== // ### SERVER-SIDE HTML CACHE - Reducer TTFB fra ~1500ms til ~50ms ### // =================================================================== // === CACHE MIDLERTIDIGT DEAKTIVERET FOR UDVIKLING === $cache_dir = null; $cache_file = null; $cache_active = false; // =================================================================== $stock_data = array(); $json_result = json_decode(file_get_contents_cus('https://'.site_api_url().'/stocks/details/' . $stock_permalink), true); $stock_data = (array) $json_result['data']; //https://'.site_api_url().'/stocks/details/agf-b if (!(boolval($stock_data['is_active'] ?? false) == true)) { header("HTTP/1.1 404 Not Found"); include('404.php'); exit; } // SEO: Definer renset virksomhedsnavn tidligt $stock_name = clean_company_name($stock_data['name']); $stock_eod_link = $stock_data['eod_import_code']; $target = $stock_data['wallstreettarget'] ?? 0.00; $trading_data = $stock_data['trading'] ?? ['history' => [], 'points' => 0]; $fundamental = $stock_data['fundamental'] ?? []; $calender = $stock_data['calendar_items'] ?? []; $next_earnings_report_date = $stock_data['next_earnings_report_date'] ?? null; // Fallback: Hvis API'en ikke returnerer next_earnings_report_date, brug calendar_items if (empty($next_earnings_report_date) && !empty($stock_data['calendar_items'])) { foreach ($stock_data['calendar_items'] as $cal_item) { $cal_date = $cal_item['report_date'] ?? null; if (!empty($cal_date) && strtotime($cal_date) >= strtotime('today')) { $next_earnings_report_date = $cal_date; break; } } } // Detect: Er regnskabet I DAG? $earnings_is_today = false; if (!empty($next_earnings_report_date)) { $earnings_is_today = (date('Y-m-d', strtotime($next_earnings_report_date)) === date('Y-m-d')); } // Trying to get newest dividend data $dividend_data = $stock_data['dividend_items'][0] ?? NULL; if ($dividend_data !== NULL) { // Access array elements with ['key'] syntax $latest_dividend_date = $dividend_data['dividend_date']; $latest_ex_date = $dividend_data['ex_date']; $latest_payment_date = $dividend_data['payment_date']; $latest_value = $dividend_data['value']; $latest_currency = $dividend_data['currency']; } if (isset($stock_data['calendar_items'][0])) { // Få data om næste regnskab $next_report = $stock_data['calendar_items'][0]; $next_earning_date = $next_report['report_date'] ?? null; $quarter_date = $next_report['date'] ?? null; // Dato for hvilket kvartal regnskabet dækker $before_after = $next_report['before_after'] ?? null; // Konverter kvartalsdatoen til en timestamp for at tjekke hvilken måned $quarter_month = (int)date('m', strtotime($quarter_date)); // Bestem hvilket kvartal der rapporteres for if ($quarter_month >= 1 && $quarter_month <= 3) { $quarter = "første kvartal (Q1)"; } elseif ($quarter_month >= 4 && $quarter_month <= 6) { $quarter = "andet kvartal (Q2)"; } elseif ($quarter_month >= 7 && $quarter_month <= 9) { $quarter = "tredje kvartal (Q3)"; } else { $quarter = "fjerde kvartal (Q4)"; } // Bestem teksten for before/after market $timing_text = ""; // Tjek for null eller tom værdi if (!empty($before_after)) { if (strcasecmp($before_after, "BeforeMarket") === 0) { $timing_text = "før markedets åbning"; } elseif (strcasecmp($before_after, "AfterMarket") === 0) { $timing_text = "efter markedets lukning"; } } else { $timing_text = "ukendt tid"; // Valgfri fallback-tekst } // Generer dynamisk tekst for næste regnskab if (isset($next_earning_date)) { // Tjek om regnskabet er I DAG if ($earnings_is_today) { $Next_earnings = "