@php $tz = new DateTimeZone('Europe/London'); $nowTs = time(); $gtE = function ($s) { return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8'); }; $img = function ($p) { $p = trim((string) $p); if ($p === '') { return ''; } return strpos($p, 'http') === 0 ? $p : 'https://xwmsys.b-cdn.net/' . ltrim($p, '/'); }; $MK = ['goals' => 'Goals', 'cards' => 'Cards', 'corners' => 'Corners', 'result' => 'Result', 'players' => 'Players']; $badgeNorm = function ($s) { $s = mb_strtolower(trim((string) $s), 'UTF-8'); $s = strtr($s, ['á'=>'a','à'=>'a','â'=>'a','ä'=>'a','ã'=>'a','å'=>'a','ç'=>'c','č'=>'c','ć'=>'c','é'=>'e','è'=>'e','ê'=>'e','ë'=>'e','ğ'=>'g','í'=>'i','î'=>'i','ï'=>'i','ı'=>'i','ł'=>'l','ñ'=>'n','ó'=>'o','ò'=>'o','ô'=>'o','ö'=>'o','õ'=>'o','ø'=>'o','š'=>'s','ş'=>'s','ß'=>'ss','ú'=>'u','ù'=>'u','û'=>'u','ü'=>'u','ž'=>'z']); $s = str_replace('&', ' and ', $s); $s = preg_replace('/[^a-z0-9 ]+/', ' ', $s); $drop = ['fc','afc','cf','sc','ac','bc','cfc','ssc','ss','as','us','ud','cd','sd','rcd','sv','vfb','tsg','fsv','bsc','sl','sk','fk','nk','ck','jk','kv','if','bk','ff','cp','tc','sa','sad','ca','rc','cs','gd','ka','kf','ks','sp','ssd','rsc','vfl','tsv','spvgg','krc','kaa','kvc','ogc','rcs','asc','spor','calcio']; $out = []; foreach (preg_split('/\s+/', trim($s)) as $t) { if ($t === '' || ctype_digit($t) || in_array($t, $drop, true)) { continue; } $out[] = $t; } return trim(implode(' ', $out)); }; $badges = []; foreach (collect(collection_items(303, ['limit' => 1000, 'order_by' => 'season_source', 'order_dir' => 'desc']))->all() as $r) { $u = (string) ($r['badge_url'] ?? ''); if ($u === '') { continue; } $k = (string) ($r['match_key'] ?? ''); if ($k !== '' && !isset($badges[$k])) { $badges[$k] = $u; } foreach (explode('|', (string) ($r['aliases'] ?? '')) as $a) { $a = trim($a); if ($a !== '' && !isset($badges[$a])) { $badges[$a] = $u; } } } $badge = function ($team) use ($badges, $badgeNorm) { $k = $badgeNorm($team); if ($k === '') { return ''; } if (isset($badges[$k])) { return $badges[$k]; } $w = explode(' ', $k); if (count($w) > 1) { $k2 = implode(' ', array_slice($w, 0, -1)); if (isset($badges[$k2])) { return $badges[$k2]; } $k3 = implode(' ', array_slice($w, 1)); if (isset($badges[$k3])) { return $badges[$k3]; } } return ''; }; $SET = []; foreach (collect(collection_items(304, ['limit' => 5000]))->all() as $sr) { if ((string) ($sr['status'] ?? '') !== 'auto') { continue; } $ss = (string) ($sr['tip_slug'] ?? ''); $sres = strtolower(trim((string) ($sr['result'] ?? ''))); if ($ss !== '' && in_array($sres, ['won', 'lost', 'void'], true) && !isset($SET[$ss])) { $SET[$ss] = ['res' => $sres, 'score' => (string) ($sr['final_score'] ?? ''), 'note' => (string) ($sr['result_note'] ?? '')]; } } $gtTipsters = []; foreach (collect(collection_items(299, ['limit' => 100, 'order_by' => 'sort_order', 'order_dir' => 'asc']))->all() as $r) { $s = (string) ($r['tipster_name_slug'] ?? ''); if ($s === '') { continue; } $gtTipsters[$s] = ['slug' => $s, 'name' => (string) ($r['tipster_name'] ?? ''), 'ini' => (string) ($r['initials'] ?? ''), 'role' => (string) ($r['role_label'] ?? ''), 'spec' => (string) ($r['specialties'] ?? ''), 'bio' => (string) ($r['short_bio'] ?? ''), 'color' => (string) (($r['avatar_color'] ?? '') ?: '#126e51'), 'mk' => (string) ($r['market_slug'] ?? ''), 'mkl' => (string) ($r['market_label'] ?? ''), 'img' => $img($r['avatar_image'] ?? '')]; } $gtTips = []; foreach (collect(collection_items(300, ['limit' => 1000, 'order_by' => 'kickoff_utc', 'order_dir' => 'asc']))->all() as $r) { $iso = trim((string) ($r['kickoff_utc'] ?? '')); $slug = (string) ($r['page_key_slug'] ?? ''); if ($iso === '' || $slug === '') { continue; } try { $d = new DateTime($iso); } catch (\Exception $ex) { continue; } $d->setTimezone($tz); $odds = (float) str_replace(',', '.', (string) ($r['odds'] ?? '0')); $stakeU = (float) ((string) ($r['stake'] ?? '0')); $res = strtolower(trim((string) ($r['result'] ?? ''))); if (!in_array($res, ['won', 'lost', 'void'], true)) { $res = 'pending'; } if ($res === 'pending' && isset($SET[$slug])) { $res = $SET[$slug]['res']; } $units = 0.0; if ($res === 'won') { $units = $stakeU * ($odds - 1); } elseif ($res === 'lost') { $units = -$stakeU; } $au = (string) ($r['author_slug'] ?? ''); $mk = $gtTipsters[$au]['mk'] ?? ''; $gtTips[] = ['slug' => $slug, 'url' => '/tips/' . $slug, 'match' => (string) ($r['match_label'] ?? ''), 'home' => (string) ($r['home_team'] ?? ''), 'away' => (string) ($r['away_team'] ?? ''), 'league' => (string) ($r['league'] ?? ''), 'market' => (string) ($r['market'] ?? ''), 'tip' => (string) ($r['tip'] ?? ''), 'odds' => $odds, 'oddsTxt' => number_format($odds, 2), 'stakeU' => $stakeU, 'author' => $au, 'mk' => $mk, 'mkl' => $MK[$mk] ?? '', 'res' => $res, 'units' => $units, 'ts' => $d->getTimestamp(), 'iso' => $iso, 'time' => $d->format('H:i'), 'dow' => $d->format('D')]; } usort($gtTips, function ($a, $b) { return $a['ts'] <=> $b['ts']; }); $gtRec = function ($list, $sinceTs = 0) { $o = ['won' => 0, 'lost' => 0, 'void' => 0, 'pending' => 0, 'n' => 0, 'units' => 0.0, 'staked' => 0.0]; foreach ($list as $t) { if ($t['ts'] < $sinceTs) { continue; } $o['n']++; $o[$t['res']]++; $o['units'] += $t['units']; if ($t['res'] === 'won' || $t['res'] === 'lost') { $o['staked'] += $t['stakeU']; } } $o['settled'] = $o['won'] + $o['lost'] + $o['void']; $dec = $o['won'] + $o['lost']; $o['ratePct'] = $dec > 0 ? (int) round($o['won'] / $dec * 100) : 0; $o['rate'] = $dec > 0 ? $o['ratePct'] . '%' : '—'; $u = round($o['units'], 1); $o['unitsTxt'] = $u > 0 ? '+' . number_format($u, 1) : number_format($u, 1); $o['unitsCls'] = $u > 0 ? 'pos' : ($u < 0 ? 'neg' : 'nil'); return $o; }; $gtUnits = function ($u) { $u = round($u, 2); return $u > 0 ? '+' . number_format($u, 2) : number_format($u, 2); }; $gtConf = function ($c, $cls = '') { return ''; }; $gtAv = function ($slug, $cls = 's36') use ($gtTipsters, $gtE) { $p = $gtTipsters[$slug] ?? null; if (!$p) { return 'GT'; } if ($p['img'] !== '') { return ''; } return '' . $gtE($p['ini']) . ''; }; $bdgPair = function ($home, $away) use ($badge, $gtE) { $h = $badge($home); $a = $badge($away); if ($h === '' && $a === '') { return ''; } return '' . ($h !== '' ? '' : '') . ($a !== '' ? '' : '') . ''; }; $gtCard = function ($t) use ($gtE, $bdgPair) { $lab = $t['market'] !== '' ? $t['market'] : ($t['mkl'] !== '' ? $t['mkl'] : 'Tip'); return ''; }; $gtNews = function ($title, $text) use ($gtE) { return '
' . $gtE($title) . '

' . $gtE($text) . '

'; }; $gtDisclaim = '

18+ only. Gamble responsibly. Tips are opinions, not guarantees. If gambling is a problem, visit begambleaware.org.

'; $gtSince30 = $nowTs - 30 * 86400; $it = isset($item) ? (is_object($item) && method_exists($item, 'toArray') ? $item->toArray() : (array) $item) : []; $f = function ($k) use ($it) { return trim((string) ($it[$k] ?? '')); }; $slug = $f('page_key_slug'); $ko = null; try { $ko = new DateTime($f('kickoff_utc') ?: 'now'); $ko->setTimezone($tz); } catch (\Exception $ex) { $ko = new DateTime('now', $tz); } $league = $f('league'); $odds = (float) str_replace(',', '.', $f('odds')); $oddsTxt = number_format($odds, 2); $conf = max(1, min(5, (int) ($f('confidence') ?: 3))); $pips = ''; for ($pi = 1; $pi <= 5; $pi++) { $pips .= ''; } $au = $gtTipsters[$f('author_slug')] ?? null; $mk = $au ? $au['mk'] : ''; $mkl = $au ? $au['mkl'] : ''; $res = strtolower($f('result')); if (!in_array($res, ['won', 'lost', 'void'], true)) { $res = 'pending'; } $ovr = ($res === 'pending' && isset($SET[$slug])) ? $SET[$slug] : null; if ($ovr) { $res = $ovr['res']; } $fScore = $ovr ? $ovr['score'] : $f('final_score'); $fNote = $ovr ? $ovr['note'] : $f('result_note'); $pubTxt = ''; if ($f('published_utc') !== '') { try { $pd = new DateTime($f('published_utc')); $pd->setTimezone($tz); $pubTxt = $pd->format('j M, H:i'); } catch (\Exception $ex) {} } $crumb = 'Home/Football/' . $gtE($league) . ''; $metaLine = $gtE($league) . ($f('venue') !== '' ? ' · ' . $gtE($f('venue')) : '') . ' · ' . $gtE($ko->format('D j M, H:i')); $byline = ($au ? $gtAv($au['slug'], 's40') . '' . $gtE($au['name']) . ' · ' . $gtE($au['role']) . '' : 'GameTipster desk') . ($pubTxt !== '' ? '·Published ' . $gtE($pubTxt) . '' : '') . ($f('read_mins') !== '' ? '·' . $gtE($f('read_mins')) . ' min read' : ''); $form = json_decode($f('form_json'), true); if (!is_array($form)) { $form = []; } $formHtml = ''; foreach ($form as $fm) { $fp = ''; foreach (str_split(strtoupper(preg_replace('/[^WDL]/i', '', (string) ($fm['form'] ?? '')))) as $ch) { if ($ch === '') { continue; } $fp .= '' . $ch . ''; } $formHtml .= '
' . $gtE($fm['team'] ?? '') . '' . $gtE($fm['scope'] ?? '') . '
' . $fp . '
' . $gtE($fm['note'] ?? '') . '
'; } $nums = json_decode($f('numbers_json'), true); if (!is_array($nums)) { $nums = []; } $numsHtml = ''; foreach ($nums as $nm) { if (is_array($nm) && count($nm) >= 2) { $numsHtml .= '
  • ' . $gtE($nm[0]) . '' . $gtE($nm[1]) . '
  • '; } } $oj = json_decode($f('odds_json'), true); if (!is_array($oj)) { $oj = []; } $gridHtml = ''; if (!empty($oj['home'])) { $gridHtml .= '
    ' . $gtE($f('home_team')) . '
    ' . $gtE($oj['home']) . '
    '; } if (!empty($oj['draw'])) { $gridHtml .= '
    Draw
    ' . $gtE($oj['draw']) . '
    '; } if (!empty($oj['away'])) { $gridHtml .= '
    ' . $gtE($f('away_team')) . '
    ' . $gtE($oj['away']) . '
    '; } $mktHtml = ''; foreach (($oj['markets'] ?? []) as $mkt) { if (is_array($mkt) && count($mkt) >= 2) { $mktHtml .= '
  • ' . $gtE($mkt[0]) . '' . $gtE($mkt[1]) . '
  • '; } } $ini = function ($name) { $w = array_values(array_filter(preg_split('/\s+/', trim(str_replace(['.', '-', "'"], ' ', $name))))); if (count($w) === 0) { return '?'; } if (count($w) === 1) { return mb_strtoupper(mb_substr($w[0], 0, 3)); } return mb_strtoupper(mb_substr($w[0], 0, 1) . mb_substr($w[count($w) - 1], 0, 1)); }; $crest = function ($team) use ($badge, $ini, $gtE) { $u = $badge($team); if ($u !== '') { return '' . $gtE($team) . ' badge'; } return '' . $gtE($ini($team)) . ''; }; $homeCrest = $crest($f('home_team')); $awayCrest = $crest($f('away_team')); $kv = '
  • Kick-off' . $gtE($ko->format('D j M, H:i')) . '
  • '; if ($f('venue') !== '') { $kv .= '
  • Venue' . $gtE($f('venue')) . '
  • '; } if ($f('referee') !== '') { $kv .= '
  • Referee' . $gtE($f('referee')) . '
  • '; } if ($f('tv') !== '') { $kv .= '
  • TV' . $gtE($f('tv')) . '
  • '; } if ($fScore !== '') { $kv .= '
  • Final score' . $gtE($fScore) . '
  • '; } $tags = array_values(array_filter(array_map('trim', explode(',', $f('tags'))))); $tagHtml = $mkl !== '' ? '' . $gtE($mkl) . ' tips' : ''; foreach ($tags as $tg) { if (strtolower($tg) === strtolower($league)) { $tagHtml .= '' . $gtE($tg) . ''; } else { $tagHtml .= '' . $gtE($tg) . ''; } } $auTips = $au ? array_filter($gtTips, function ($t) use ($au) { return $t['author'] === $au['slug']; }) : []; $auRec = $gtRec($auTips); $auLine = $au ? ($auRec['settled'] > 0 ? $au['role'] . ' · ' . $auRec['rate'] . ' win rate · ' . $auRec['unitsTxt'] . ' units' : $au['role'] . ' · ' . count($auTips) . ' tips published') : ''; $auFirst = $au ? explode(' ', $au['name'])[0] : ''; $more = []; foreach ($gtTips as $t) { if ($t['slug'] !== $slug && $t['res'] === 'pending' && $t['ts'] > $nowTs) { $more[] = $t; } } $koTs = $ko->getTimestamp(); usort($more, function ($a, $b) use ($koTs, $mk) { $sa = $a['mk'] === $mk ? 0 : 1; $sb = $b['mk'] === $mk ? 0 : 1; return $sa <=> $sb ?: abs($a['ts'] - $koTs) <=> abs($b['ts'] - $koTs); }); $moreHtml = ''; foreach (array_slice($more, 0, 3) as $t) { $moreHtml .= $gtCard($t); } $rec30 = $gtRec($gtTips, $gtSince30); $started = $koTs <= $nowTs; $resultBar = ''; if ($res !== 'pending') { $u = $res === 'won' ? ((float) $f('stake')) * ($odds - 1) : ($res === 'lost' ? -((float) $f('stake')) : 0); $resultBar = '
    ' . ucfirst($res) . '' . ($fScore !== '' ? 'Final score ' . $gtE($fScore) . ' · ' : '') . 'Settled at ' . $gtE($oddsTxt) . ' for ' . $gtE($gtUnits($u)) . ' units.' . ($fNote !== '' ? ' ' . $gtE($fNote) : '') . '
    '; } elseif ($started) { $resultBar = '
    PendingThis match has started. The tip is settled on the Results page once the result is confirmed.
    '; } $featBadge = strtolower($f('is_featured')) === 'yes' ? 'Tip of the day' : ''; $mkBadge = $mkl !== '' ? '' . $gtE($mkl) . '' : ''; $at = chr(64); $ld = [$at . 'context' => 'https://schema.org', $at . 'type' => 'Article', 'headline' => $f('headline'), 'description' => $f('standfirst'), 'datePublished' => $f('published_utc'), 'author' => [$at . 'type' => 'Person', 'name' => $au ? $au['name'] : 'GameTipster'], 'publisher' => [$at . 'type' => 'Organization', 'name' => 'GameTipster.com'], 'mainEntityOfPage' => 'https://gametipster.com/tips/' . $slug, 'about' => [$at . 'type' => 'SportsEvent', 'name' => $f('match_label'), 'startDate' => $f('kickoff_utc'), 'location' => [$at . 'type' => 'Place', 'name' => $f('venue')]]]; if ($f('image_url') !== '') { $ld['image'] = $f('image_url'); } $ldJson = json_encode($ld, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $V = ['headline' => $f('headline'), 'standfirst' => $f('standfirst'), 'tip' => $f('tip'), 'stake' => $f('stake'), 'odds' => $oddsTxt, 'case_title' => $f('case_title') ?: 'Match analysis', 'image' => $f('image_url'), 'img_alt' => $f('venue') ?: $f('match_label'), 'caption' => $f('image_caption'), 'credit' => $f('image_credit'), 'risk' => $f('risk'), 'match' => $f('match_label'), 'kotime' => $ko->format('D H:i'), 'odds_time' => $f('odds_time'), 'slug' => $slug, 'home' => $f('home_team'), 'away' => $f('away_team'), 'home_meta' => $f('home_meta'), 'away_meta' => $f('away_meta'), 'conf' => (string) $conf, 'au_line' => $auLine, 'au_first' => $auFirst, 'au_name' => $au ? $au['name'] : 'GameTipster', 'odds_note' => $f('odds_time') ?: 'Odds correct when published, subject to change.', 'mk' => $mk, 'mkl' => $mkl, 'market' => $f('market') ?: $mkl, 'pred_k' => 'Our prediction · ' . ($f('market') ?: ($mkl !== '' ? $mkl : 'Tip')), 'more_t' => $mkl !== '' ? 'More ' . strtolower($mkl) . ' tips' : 'More tips']; $H = ['case' => $f('case_html'), 'news' => $f('team_news'), 'verdict' => $f('verdict'), 'sources' => $f('sources'), 'pips' => $pips]; @endphp
    {!! $featBadge !!}{!! $mkBadge !!}{!! $metaLine !!}

    {{ $V['headline'] }}

    {{ $V['standfirst'] }}

    The prediction is at the end of the analysis ↓
    {!! $resultBar !!}

    {{ $V['case_title'] }}

    {!! $H['case'] !!} @if($V['image'] !== '')
    {{ $V['img_alt'] }}
    {{ $V['caption'] }}{{ $V['credit'] }}
    @endif @if($formHtml !== '')

    Form guide

    {!! $formHtml !!}
    @endif @if($numsHtml !== '')

    Key numbers

      {!! $numsHtml !!}
    @endif @if($H['news'] !== '')

    Team news

    {!! $H['news'] !!} @endif @if($V['risk'] !== '')
    The risk

    {{ $V['risk'] }}

    @endif

    Verdict

    {!! $H['verdict'] !!}
    {{ $V['pred_k'] }}{{ $V['match'] }} · {{ $V['kotime'] }} · by {{ $V['au_name'] }}
    {{ $V['tip'] }}
    Best odds{{ $V['odds'] }}
    Stake{{ $V['stake'] }}
    Confidence {{ $V['conf'] }}/5{!! $H['pips'] !!}
    {{ $V['odds_note'] }}
    @if($H['sources'] !== '')
    Sources{!! $H['sources'] !!}
    @endif
    {{ $V['match'] }} · {{ $V['kotime'] }}
    {{ $V['tip'] }} @ {{ $V['odds'] }}
    {{ $V['odds_time'] }}
    {!! $tagHtml !!}
    @if($au)
    {!! $gtAv($au['slug'], 's56') !!}
    {{ $au['name'] }}
    {{ $V['au_line'] }}

    {{ $au['bio'] }}

    All tips by {{ $V['au_first'] }} →
    @endif @if($moreHtml !== '')

    More predictions

    {!! $moreHtml !!}
    @endif