dabanh

<?php
/**
 * Lịch trực tiếp bóng đá - WordPress Shortcode
 * Sử dụng: [live_soccer]
 * Hoặc: [live_soccer bg="URL_HINH_NEN"]
 */

add_shortcode('live_soccer', function($atts) {
    $atts = shortcode_atts([
        'bg' => 'https://cdn-media.sforum.vn/storage/app/media/wp-content/uploads/2023/06/hinh-nen-bong-da-thumb.jpg',
    ], $atts);

    ob_start();
    
    // Constants
    define('SOCCER_BASE', 'https://livesoccerapi.com');
    define('SOCCER_SRC_PATH', '/truc-tiep-bong-da/');
    define('SOCCER_GOLD1', '#f6e3b0');
    define('SOCCER_GOLD2', '#8f6a2b');
    
    // Helper functions
    function soccer_http_get($url) {
        $response = wp_remote_get($url, [
            'timeout' => 25,
            'sslverify' => false,
            'headers' => [
                'User-Agent' => 'Mozilla/5.0'
            ]
        ]);
        
        if (is_wp_error($response)) {
            return '';
        }
        
        return wp_remote_retrieve_body($response);
    }
    
    function soccer_xpath_new($html) {
        libxml_use_internal_errors(true);
        $dom = new DOMDocument();
        $dom->loadHTML('<?xml encoding="utf-8" ?>' . $html);
        libxml_clear_errors();
        return new DOMXPath($dom);
    }
    
    function soccer_xp_first_text($xp, $ctx, $q) {
        $n = $xp->query($q, $ctx);
        if ($n && $n->length) {
            return trim(preg_replace('/\s+/u', ' ', $n->item(0)->textContent));
        }
        return null;
    }
    
    function soccer_xp_first_attr($xp, $ctx, $q, $attr) {
        $n = $xp->query($q, $ctx);
        if ($n && $n->length) {
            $el = $n->item(0);
            $v = $el->getAttribute($attr);
            return $v !== '' ? $v : null;
        }
        return null;
    }
    
    function soccer_clean_team_name($s) {
        $s = (string)$s;
        $s = preg_replace('/[&#].*$/u', '', $s);
        $s = preg_replace('/\s+/u', ' ', $s);
        $s = trim($s, " \t\n\r\0\x0B-–—·•|");
        return trim($s);
    }
    
    function soccer_build_url($page, $bg) {
        $current_url = add_query_arg(null, null);
        return add_query_arg(['soccer_page' => $page], remove_query_arg(['soccer_page', 'q', 'live'], $current_url));
    }
    
    // Get page number
    $p = max(1, isset($_GET['soccer_page']) ? intval($_GET['soccer_page']) : 1);
    $bg = esc_url($atts['bg']);
    
    // Fetch data
    $srcUrl = SOCCER_BASE . SOCCER_SRC_PATH . '?page=' . $p;
    $html = soccer_http_get($srcUrl);
    $xp = soccer_xpath_new($html);
    
    $cards = $xp->query("//div[contains(@class,'card') and contains(@class,'matches')]");
    $matches = [];
    
    foreach ($cards as $card) {
        $date = soccer_xp_first_text($xp, $card, ".//div[contains(@class,'date-match')]");
        $home_name = soccer_xp_first_text($xp, $card, ".//div[contains(@class,'team-home')]//div[1]");
        $home_img = soccer_xp_first_attr($xp, $card, ".//div[contains(@class,'team-home')]//img", "src");
        $away_name = soccer_xp_first_text($xp, $card, ".//div[contains(@class,'team-away')]//div[1]");
        $away_img = soccer_xp_first_attr($xp, $card, ".//div[contains(@class,'team-away')]//img", "src");
        $score = soccer_xp_first_text($xp, $card, ".//div[contains(@class,'score')]");
        $league_bottom = soccer_xp_first_text($xp, $card, ".//div[contains(@class,'status') and not(contains(@class,'green'))]");
        $league_top = soccer_xp_first_text($xp, $card, ".//div[contains(@class,'status') and contains(@class,'green')]");
        $home_name = soccer_clean_team_name($home_name);
        $away_name = soccer_clean_team_name($away_name);
        $detail = soccer_xp_first_attr($xp, $card, ".//a[contains(@class,'toDetail')]", "href");
        if ($detail && strpos($detail, 'http') !== 0) {
            $detail = SOCCER_BASE . $detail;
        }
        
        $is_live = false;
        $liveNode = $xp->query(".//div[contains(@class,'bet')]//h5[contains(@class,'live-match')]", $card);
        if ($liveNode && $liveNode->length && strtoupper(trim($liveNode->item(0)->textContent)) === 'LIVE') {
            $is_live = true;
        }
        
        $matches[] = [
            'date' => $date ?: 'N/A',
            'home' => $home_name,
            'home_img' => $home_img,
            'away' => $away_name,
            'away_img' => $away_img,
            'time_or_score' => $score ?: '',
            'league_top' => $league_top ?: '',
            'league' => $league_bottom ?: '',
            'detail' => $detail,
            'is_live' => $is_live,
        ];
    }
    
    // Pagination
    $paginationLinks = [];
    if ($aNodes = $xp->query("//a[contains(@href,'?page=')]")) {
        foreach ($aNodes as $a) {
            $href = $a->getAttribute('href');
            if (preg_match('/[?&]page=(\d+)/', $href, $m)) {
                $paginationLinks[(int)$m[1]] = true;
            }
        }
    }
    $totalPages = max(1, !empty($paginationLinks) ? max(array_keys($paginationLinks)) : 1);
    
    // Group by date
    $byDate = [];
    foreach ($matches as $m) {
        $byDate[$m['date']][] = $m;
    }
    
    ?>
    <style>
    .soccer-wrap {
        font-family: Inter, system-ui, Arial;
        background: #0b0f1a url('<?php echo $bg; ?>') center/cover fixed no-repeat;
        color: #1a2537;
        max-width: 1280px;
        margin: 0 auto;
        padding: 20px;
        border-radius: 12px;
    }
    .soccer-wrap * { box-sizing: border-box; }
    .soccer-page-title {
        color: #fff;
        font-weight: 900;
        font-size: 26px;
        text-align: center;
        margin-bottom: 20px;
    }
    #soccer-video-section {
        display: none;
        max-width: 1200px;
        margin: 20px auto;
        background: linear-gradient(180deg, #081228, #0a1a34);
        border-radius: 14px;
        border: 1px solid #1a2f55;
        overflow: hidden;
        position: relative;
    }
    #soccer-video-section.active { display: block; }
    .soccer-close-video {
        position: absolute;
        top: 12px;
        right: 12px;
        z-index: 1000;
        background: rgba(231, 76, 60, 0.95);
        color: #fff;
        border: none;
        width: 42px;
        height: 42px;
        border-radius: 50%;
        cursor: pointer;
        font-weight: 700;
        font-size: 20px;
        display: flex;
        align-items: center;
        justify-content: center;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
        transition: all 0.3s ease;
    }
    .soccer-close-video:hover {
        background: rgba(192, 57, 43, 1);
        transform: scale(1.1);
    }
    #soccer-player-container {
        width: 100%;
        aspect-ratio: 16/9;
        background: #000;
        position: relative;
    }
    #soccer-player-container iframe {
        width: 100%;
        height: 100%;
        border: none;
    }
    .soccer-ad-banner {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 80px;
        background: #ff0000;
        z-index: 999;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #fff;
        font-weight: 900;
        font-size: 20px;
    }
    .soccer-loading {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;
        color: #fff;
        font-size: 18px;
    }
    .soccer-date-pill {
        background: rgba(255, 255, 255, .15);
        padding: 6px 12px;
        border-radius: 12px;
        color: #fff;
        font-weight: 800;
        margin: 12px auto;
        display: block;
        width: max-content;
    }
    .soccer-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
        gap: 16px;
        justify-content: center;
        padding: 0 12px;
        margin-bottom: 20px;
    }
    .soccer-match-link {
        display: block;
        text-decoration: none;
        color: inherit;
        cursor: pointer;
    }
    .soccer-match-card {
        position: relative;
        border-radius: 12px;
        overflow: hidden;
        background: linear-gradient(180deg, #ffffff, #eef2f8);
        box-shadow: 0 8px 20px rgba(0, 0, 0, .35);
        margin: 0 auto;
        transition: transform .2s;
        max-width: 95%;
    }
    .soccer-match-card:hover { transform: translateY(-2px); }
    .soccer-match-card::before {
        content: "";
        position: absolute;
        inset: -1px;
        border-radius: 12px;
        padding: .5px;
        background: linear-gradient(135deg, <?php echo SOCCER_GOLD1; ?>, <?php echo SOCCER_GOLD2; ?>);
        -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
        -webkit-mask-composite: xor;
        mask-composite: exclude;
        pointer-events: none;
    }
    .soccer-card-top {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 10px 12px 0;
    }
    .soccer-time-tag {
        font-size: 13px;
        font-weight: 900;
        background: #fff;
        border: 1px solid #e4e7ef;
        padding: 4px 8px;
        border-radius: 6px;
    }
    .soccer-league-tag {
        font-size: 12px;
        font-weight: 900;
        background: #e8f7f0;
        color: #0f5132;
        border: 1px solid #b6e1cf;
        padding: 4px 8px;
        border-radius: 6px;
        white-space: nowrap;
        max-width: 60%;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .soccer-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 10px 12px;
    }
    .soccer-team {
        flex: 1;
        display: flex;
        align-items: center;
        gap: 10px;
        min-width: 0;
    }
    .soccer-team.right {
        flex-direction: row-reverse;
        text-align: right;
    }
    .soccer-logo {
        width: 56px;
        height: 56px;
        display: grid;
        place-items: center;
        background: #fff;
        border-radius: 8px;
        border: 1px solid #e2e6f1;
        overflow: hidden;
    }
    .soccer-logo img {
        max-width: 100%;
        max-height: 100%;
    }
    .soccer-name {
        font-size: 13px;
        font-weight: 800;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 150px;
        color: #1b2435;
    }
    .soccer-vs {
        display: grid;
        place-items: center;
        min-width: 36px;
        height: 36px;
        padding: 0 8px;
        border-radius: 8px;
        background: #fff;
        border: 1px solid #e4e7ef;
        font-weight: 900;
        color: #2a3a53;
        font-size: 12px;
    }
    .soccer-card-bottom {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        padding: 0 12px 12px;
    }
    .soccer-btn {
        padding: 7px 10px;
        border-radius: 8px;
        font-weight: 800;
        font-size: 12.5px;
        text-align: center;
        min-width: 110px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    .soccer-btn-muted {
        background: #eef2f8;
        color: #364760;
    }
    .soccer-btn-primary {
        background: #ffc94a;
        color: #1b1203;
    }
    .soccer-btn-live {
        background: #e74c3c;
        color: #fff;
    }
    .soccer-pagination {
        display: flex;
        gap: 6px;
        flex-wrap: wrap;
        margin: 24px auto;
        justify-content: center;
    }
    .soccer-pagination a,
    .soccer-pagination span {
        padding: 8px 12px;
        border: 1px solid rgba(255, 255, 255, .4);
        border-radius: 10px;
        background: rgba(255, 255, 255, .15);
        color: #fff;
        text-decoration: none;
        font-weight: 700;
    }
    .soccer-pagination .active {
        background: #3b82f6;
        border-color: #3b82f6;
        color: #fff;
    }
    .soccer-pagination .disabled {
        opacity: .45;
        pointer-events: none;
    }
    @media(max-width:640px) {
        .soccer-grid {
            grid-template-columns: 1fr;
            gap: 14px;
        }
        .soccer-match-card { max-width: 92%; }
        .soccer-page-title { font-size: 20px; }
        .soccer-name {
            max-width: 65vw;
            font-size: 12px;
        }
        .soccer-logo {
            width: 44px;
            height: 44px;
        }
        .soccer-vs {
            min-width: 30px;
            height: 30px;
            font-size: 11px;
        }
        #soccer-player-container {
            height: 50vh;
            aspect-ratio: unset;
        }
        .soccer-ad-banner {
            height: 70px;
            font-size: 16px;
        }
        .soccer-close-video {
            width: 36px;
            height: 36px;
            font-size: 18px;
        }
    }
    </style>

    <div class="soccer-wrap">
        <div class="soccer-page-title">Lịch trực tiếp bóng đá</div>

        <div id="soccer-video-section">
            <button class="soccer-close-video" onclick="soccerCloseVideo()">✕</button>
            <div id="soccer-player-container">
                <div class="soccer-ad-banner">🚫 BANNER CHE QUẢNG CÁO</div>
                <div class="soccer-loading">Đang tải video...</div>
            </div>
        </div>

        <?php if (empty($byDate)): ?>
        <div class="soccer-date-pill">Không có trận phù hợp ở trang <?php echo (int)$p; ?>.</div>
        <?php else: ?>
            <?php foreach ($byDate as $date => $items): ?>
            <div class="soccer-date-pill"><?php echo esc_html($date); ?></div>
            <div class="soccer-grid">
                <?php foreach ($items as $idx => $m): ?>
                <div class="soccer-match-link" onclick="soccerPlayMatch(<?php echo $idx; ?>)">
                    <div class="soccer-match-card">
                        <div class="soccer-card-top">
                            <div class="soccer-time-tag"><?php echo esc_html($m['time_or_score'] ?: '—'); ?></div>
                            <?php if (!empty($m['league_top'])): ?>
                            <div class="soccer-league-tag" title="<?php echo esc_attr($m['league_top']); ?>">
                                <?php echo esc_html($m['league_top']); ?>
                            </div>
                            <?php endif; ?>
                        </div>
                        <div class="soccer-row">
                            <div class="soccer-team">
                                <div class="soccer-logo">
                                    <?php if (!empty($m['home_img'])): ?>
                                    <img src="<?php echo esc_url($m['home_img']); ?>" alt="<?php echo esc_attr($m['home']); ?>">
                                    <?php endif; ?>
                                </div>
                                <div class="soccer-name"><?php echo esc_html($m['home']); ?></div>
                            </div>
                            <div class="soccer-vs">VS</div>
                            <div class="soccer-team right">
                                <div class="soccer-logo">
                                    <?php if (!empty($m['away_img'])): ?>
                                    <img src="<?php echo esc_url($m['away_img']); ?>" alt="<?php echo esc_attr($m['away']); ?>">
                                    <?php endif; ?>
                                </div>
                                <div class="soccer-name"><?php echo esc_html($m['away']); ?></div>
                            </div>
                        </div>
                        <div class="soccer-card-bottom">
                            <?php if ($m['is_live']): ?>
                            <div class="soccer-btn soccer-btn-live">Đang diễn ra</div>
                            <?php else: ?>
                            <div class="soccer-btn soccer-btn-muted">Chưa bắt đầu</div>
                            <?php endif; ?>
                            <div class="soccer-btn soccer-btn-primary">Xem trận</div>
                        </div>
                    </div>
                </div>
                <?php endforeach; ?>
            </div>
            <?php endforeach; ?>
        <?php endif; ?>

        <div class="soccer-pagination">
            <?php
            $prev = max(1, $p - 1);
            $next = min($totalPages, $p + 1);
            $last = max(1, (int)$totalPages);
            $window = 2;
            $start = max(1, $p - $window);
            $end = min($last, $p + $window);
            
            echo '<a class="' . ($p <= 1 ? 'disabled' : '') . '" href="' . esc_url(soccer_build_url($prev, $bg)) . '">« Trước</a>';
            
            if ($start > 1) {
                echo '<a href="' . esc_url(soccer_build_url(1, $bg)) . '">1</a>';
                if ($start > 2) echo '<span class="disabled">…</span>';
            }
            
            for ($i = $start; $i <= $end; $i++) {
                if ($i == $p) {
                    echo '<span class="active">' . $i . '</span>';
                } else {
                    echo '<a href="' . esc_url(soccer_build_url($i, $bg)) . '">' . $i . '</a>';
                }
            }
            
            if ($end < $last) {
                if ($end < $last - 1) echo '<span class="disabled">…</span>';
                echo '<a href="' . esc_url(soccer_build_url($last, $bg)) . '">' . $last . '</a>';
            }
            
            echo '<a class="' . ($p >= $last ? 'disabled' : '') . '" href="' . esc_url(soccer_build_url($next, $bg)) . '">Sau »</a>';
            ?>
        </div>
    </div>

    <script>
    const soccerMatches = <?php echo json_encode($matches); ?>;

    function soccerPlayMatch(idx) {
        const match = soccerMatches[idx];
        if (!match || !match.detail) {
            alert('Không có link video');
            return;
        }

        document.getElementById('soccer-video-section').classList.add('active');
        document.getElementById('soccer-video-section').scrollIntoView({
            behavior: 'smooth'
        });

        soccerLoadIframe(match.detail);
    }

    function soccerLoadIframe(url) {
        const container = document.getElementById('soccer-player-container');
        const banner = container.querySelector('.soccer-ad-banner');

        const iframe = document.createElement('iframe');
        iframe.src = url;
        iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-presentation');
        iframe.allowFullscreen = true;
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';
        iframe.setAttribute('scrolling', 'no');
        iframe.setAttribute('frameborder', '0');

        container.innerHTML = '';
        container.appendChild(iframe);
        if (banner) container.appendChild(banner);
    }

    function soccerCloseVideo() {
        document.getElementById('soccer-video-section').classList.remove('active');
        const container = document.getElementById('soccer-player-container');
        container.innerHTML = '<div class="soccer-ad-banner">🚫 BANNER CHE QUẢNG CÁO</div><div class="soccer-loading">Đang tải video...</div>';
        window.scrollTo({ top: 0, behavior: 'smooth' });
    }
    </script>
    <?php
    
    return ob_get_clean();
});