Jump to content

Widget:UPDEvents: Difference between revisions

From Iskomunidad
Created page with " <?php →* * UP Diliman Events feed for Iskomunidad. * Retrieves up to five upcoming events from upd.edu.ph.: header('Content-Type: application/json; charset=utf-8'); header('Cache-Control: public, max-age=900'); date_default_timezone_set('Asia/Manila'); $sourceUrl = 'https://upd.edu.ph/events-list/'; function respond($events, $status = 200) { http_response_code($status); echo json_encode( $events, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_..."
 
No edit summary
Line 1: Line 1:


<?php
<includeonly>
/**
<div id="upd-events-widget" class="upd-events-widget">
* UP Diliman Events feed for Iskomunidad.
    <div class="upd-events-loading">
* Retrieves up to five upcoming events from upd.edu.ph.
        Loading UP Diliman events...
*/
    </div>


header('Content-Type: application/json; charset=utf-8');
    <ul class="upd-events-list" style="display:none;"></ul>
header('Cache-Control: public, max-age=900');


date_default_timezone_set('Asia/Manila');
    <div class="upd-events-error" style="display:none;">
        Events are temporarily unavailable.
        <a href="https://upd.edu.ph/events-list/" target="_blank" rel="noopener">
            View the official events list
        </a>.
    </div>


$sourceUrl = 'https://upd.edu.ph/events-list/';
    <div class="upd-events-footer">
        <a href="https://upd.edu.ph/events/" target="_blank" rel="noopener">
            View all UP Diliman events →
        </a>
    </div>
</div>


function respond($events, $status = 200) {
<style>
     http_response_code($status);
.upd-events-widget {
     echo json_encode(
     width: 100%;
        $events,
     box-sizing: border-box;
        JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
     color: #000;
    );
     exit;
}
}


if (!function_exists('curl_init')) {
.upd-events-widget .upd-events-list {
     respond(['error' => 'PHP cURL is not installed.'], 500);
     list-style: none;
    padding: 0;
    margin: 0;
}
}


$ch = curl_init($sourceUrl);
.upd-events-widget .upd-events-list li {
    padding: 10px 0;
    border-bottom: 1px solid #e5e5e5;
    line-height: 1.5;
}


curl_setopt_array($ch, [
.upd-events-widget .upd-events-list li:last-child {
    CURLOPT_RETURNTRANSFER => true,
     border-bottom: none;
    CURLOPT_FOLLOWLOCATION => true,
}
    CURLOPT_MAXREDIRS => 3,
    CURLOPT_CONNECTTIMEOUT => 8,
    CURLOPT_TIMEOUT => 15,
    CURLOPT_USERAGENT => 'Iskomunidad-Events/1.0',
     CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
]);


$html = curl_exec($ch);
.upd-events-widget .upd-events-list a {
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    color: #850038 !important;
$error = curl_error($ch);
    text-decoration: none;
curl_close($ch);
    font-weight: 500;
}


if ($html === false || $httpCode < 200 || $httpCode >= 300) {
.upd-events-widget .upd-events-list a:hover {
     error_log('UPD events retrieval failed: ' . $error);
     text-decoration: underline;
    respond(['error' => 'The UP Diliman events page is temporarily unavailable.'], 502);
}
}


libxml_use_internal_errors(true);
.upd-events-widget .upd-events-loading,
.upd-events-widget .upd-events-error {
    padding: 8px 0;
    color: #333;
}


$dom = new DOMDocument();
.upd-events-widget .upd-events-footer {
$loaded = $dom->loadHTML('<?xml encoding="UTF-8">' . $html);
    margin-top: 12px;
    font-size: 0.9em;
}


libxml_clear_errors();
.upd-events-widget .upd-events-footer a {
    color: #850038 !important;
    text-decoration: none;
}


if (!$loaded) {
.upd-events-widget .upd-events-footer a:hover {
     respond(['error' => 'Could not parse the UP Diliman events page.'], 502);
     text-decoration: underline;
}
}
</style>


$xpath = new DOMXPath($dom);
<script>
$links = $xpath->query('//a[@href]');
(function () {
$today = new DateTimeImmutable('today', new DateTimeZone('Asia/Manila'));
    "use strict";


$events = [];
    var widgets = document.querySelectorAll(
$seen = [];
        '.upd-events-widget:not([data-loaded])'
    );


foreach ($links as $link) {
     widgets.forEach(function (widget) {
     $url = trim($link->getAttribute('href'));
        widget.setAttribute('data-loaded', 'true');
    $title = trim(preg_replace('/\s+/u', ' ', $link->textContent));


    // Only accept links to individual UP Diliman event pages.
        var loading = widget.querySelector('.upd-events-loading');
    $path = parse_url($url, PHP_URL_PATH) ?: '';
        var list = widget.querySelector('.upd-events-list');
        var error = widget.querySelector('.upd-events-error');


    if (!preg_match('~^/events/[^/]+/$~', $path)) {
        // Endpoint on the same Iskomunidad server.
        continue;
        var endpoint = '/upd-events-proxy.php';
    }


    // Event URLs contain their start date, e.g. ...-2026-10-26/
        fetch(endpoint, {
    if (!preg_match('/-(\d{4}-\d{2}-\d{2})\/?$/', $path, $match)) {
            method: 'GET',
        continue;
            credentials: 'same-origin',
    }
            cache: 'no-cache'
        })
        .then(function (response) {
            if (!response.ok) {
                throw new Error('Could not load events.');
            }
            return response.json();
        })
        .then(function (events) {
            if (!Array.isArray(events)) {
                throw new Error('Unexpected event data.');
            }


    $dateString = $match[1];
            loading.style.display = 'none';


    $eventDate = DateTimeImmutable::createFromFormat(
            if (events.length === 0) {
        '!Y-m-d',
                error.style.display = 'block';
        $dateString,
                error.textContent =
        new DateTimeZone('Asia/Manila')
                    'No upcoming events were found. ';
    );
                var link = document.createElement('a');
                link.href = 'https://upd.edu.ph/events-list/';
                link.target = '_blank';
                link.rel = 'noopener';
                link.textContent = 'View the official events list';
                error.appendChild(link);
                error.appendChild(document.createTextNode('.'));
                return;
            }


    if (!$eventDate || $eventDate->format('Y-m-d') !== $dateString) {
            events.slice(0, 5).forEach(function (event) {
        continue;
                if (!event.title || !event.url) {
    }
                    return;
                }


    // Include events starting today or later.
                // Only allow official UP Diliman event links.
    if ($eventDate < $today) {
                var url;
        continue;
                try {
    }
                    url = new URL(event.url);
                } catch (e) {
                    return;
                }


    if ($title === '' || isset($seen[$path])) {
                if (
        continue;
                    url.protocol !== 'https:' ||
    }
                    url.hostname !== 'upd.edu.ph' ||
                    !url.pathname.startsWith('/events/')
                ) {
                    return;
                }


    $seen[$path] = true;
                var item = document.createElement('li');
                var anchor = document.createElement('a');


    $events[] = [
                anchor.href = url.href;
        'title' => $title,
                anchor.target = '_blank';
        'url' => 'https://upd.edu.ph' . $path,
                anchor.rel = 'noopener noreferrer';
        'date' => $dateString,
                anchor.textContent = event.title;
    ];
}


// Sort by event start date, earliest first.
                item.appendChild(anchor);
usort($events, function ($a, $b) {
                list.appendChild(item);
    return strcmp($a['date'], $b['date']);
            });
});


respond(array_slice($events, 0, 5));
            if (list.children.length === 0) {
                error.style.display = 'block';
            } else {
                list.style.display = 'block';
            }
        })
        .catch(function (err) {
            console.error('UP Diliman Events widget:', err);
            loading.style.display = 'none';
            error.style.display = 'block';
        });
    });
})();
</script>
</includeonly>

Revision as of 01:27, 29 October 2026