| Server IP : 172.67.191.97 / Your IP : 104.23.243.196 Web Server : Apache/2.4.63 (Ubuntu) System : Linux adminpruebas-Virtual-Machine 6.14.0-37-generic #37-Ubuntu SMP PREEMPT_DYNAMIC Fri Nov 14 22:10:32 UTC 2025 x86_64 User : www-data ( 33) PHP Version : 8.4.5 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /proc/self/root/var/www/biblioteca/ |
Upload File : |
<?php
declare(strict_types=1);
require_once __DIR__ . '/includes/tutoriales_helpers.php';
$rawTutorials = require __DIR__ . '/data/tutoriales.php';
$tutorials = array_map('prepareTutorial', $rawTutorials);
$categoryLabels = [
'services' => 'Tutoriales de servicios',
'resources' => 'Tutoriales de recursos bibliográficos',
];
$requestedTutorialId = trim((string) ($_GET['tutorial'] ?? ''));
$activeTutorial = null;
if ($requestedTutorialId !== '') {
foreach ($tutorials as $tutorial) {
if ((string) ($tutorial['id'] ?? '') === $requestedTutorialId) {
$activeTutorial = $tutorial;
break;
}
}
}
if ($activeTutorial === null) {
foreach ($tutorials as $tutorial) {
if (!empty($tutorial['has_media'])) {
$activeTutorial = $tutorial;
break;
}
}
}
$activeTutorial = $activeTutorial ?? ($tutorials[0] ?? null);
if (!is_array($activeTutorial)) {
http_response_code(500);
echo 'No hay tutoriales configurados.';
exit;
}
$tutorialsByCategory = [];
foreach ($categoryLabels as $categoryKey => $_label) {
$tutorialsByCategory[$categoryKey] = [];
}
foreach ($tutorials as $tutorial) {
$categoryKey = (string) ($tutorial['category'] ?? 'resources');
if (!array_key_exists($categoryKey, $tutorialsByCategory)) {
$tutorialsByCategory[$categoryKey] = [];
}
$tutorialsByCategory[$categoryKey][] = $tutorial;
}
$tutorialsJson = json_encode(
$tutorials,
JSON_UNESCAPED_SLASHES
| JSON_UNESCAPED_UNICODE
| JSON_HEX_TAG
| JSON_HEX_AMP
| JSON_HEX_APOS
| JSON_HEX_QUOT
);
?>
<!doctype html>
<html lang="es">
<head>
<?php
$titulo = 'Tutoriales - Biblioteca Unillanos';
include __DIR__ . '/includes/head.php';
?>
<link rel="stylesheet" href="css/tutoriales.css" />
</head>
<body class="tutorials-page">
<?php include __DIR__ . '/includes/encabezado.php'; ?>
<main class="container page-wrap">
<section
id="tutoriales-principal"
class="tutorials-shell"
data-tutorials-root
data-initial-tutorial="<?= htmlspecialchars((string) $activeTutorial['id'], ENT_QUOTES, 'UTF-8') ?>"
>
<aside class="tutorials-nav" aria-label="Listado de tutoriales">
<div class="tutorials-nav-copy">
<p class="tutorials-nav-intro">Selecciona cuál de estos recursos o servicios te interesa conocer más.</p>
</div>
<div class="tutorials-groups">
<?php foreach ($categoryLabels as $categoryKey => $categoryLabel): ?>
<?php
$groupTutorials = $tutorialsByCategory[$categoryKey] ?? [];
if ($groupTutorials === []) {
continue;
}
$groupId = 'tutorial-group-' . $categoryKey;
$isOpen = (($activeTutorial['category'] ?? 'resources') === $categoryKey);
?>
<section
class="tutorial-group<?= $isOpen ? ' is-open' : '' ?>"
data-tutorial-group="<?= htmlspecialchars($categoryKey, ENT_QUOTES, 'UTF-8') ?>"
>
<button
type="button"
class="tutorials-group-toggle"
data-group-toggle
aria-expanded="<?= $isOpen ? 'true' : 'false' ?>"
aria-controls="<?= htmlspecialchars($groupId, ENT_QUOTES, 'UTF-8') ?>"
>
<span class="tutorials-group-title"><?= htmlspecialchars($categoryLabel, ENT_QUOTES, 'UTF-8') ?></span>
<span class="tutorials-group-icon" aria-hidden="true"></span>
</button>
<div
class="tutorials-group-panel"
id="<?= htmlspecialchars($groupId, ENT_QUOTES, 'UTF-8') ?>"
<?= $isOpen ? '' : 'hidden' ?>
>
<div
class="tutorials-list"
role="tablist"
aria-orientation="vertical"
aria-label="<?= htmlspecialchars($categoryLabel, ENT_QUOTES, 'UTF-8') ?>"
>
<?php foreach ($groupTutorials as $tutorial): ?>
<?php
$id = (string) $tutorial['id'];
$name = (string) $tutorial['name'];
$accent = (string) $tutorial['accent'];
$isActive = $activeTutorial['id'] === $id;
?>
<button
type="button"
class="tutorial-trigger<?= $isActive ? ' is-active' : '' ?>"
role="tab"
id="tutorial-tab-<?= htmlspecialchars($id, ENT_QUOTES, 'UTF-8') ?>"
aria-selected="<?= $isActive ? 'true' : 'false' ?>"
aria-controls="tutorialStage"
data-tutorial-id="<?= htmlspecialchars($id, ENT_QUOTES, 'UTF-8') ?>"
data-tutorial-group="<?= htmlspecialchars($categoryKey, ENT_QUOTES, 'UTF-8') ?>"
style="--tutorial-accent: <?= htmlspecialchars($accent, ENT_QUOTES, 'UTF-8') ?>"
>
<span class="tutorial-name"><?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?></span>
</button>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endforeach; ?>
</div>
</aside>
<section
class="tutorial-stage"
id="tutorialStage"
role="tabpanel"
aria-labelledby="tutorial-tab-<?= htmlspecialchars((string) $activeTutorial['id'], ENT_QUOTES, 'UTF-8') ?>"
style="--tutorial-accent: <?= htmlspecialchars((string) $activeTutorial['accent'], ENT_QUOTES, 'UTF-8') ?>"
>
<div class="tutorial-stage-copy">
<div class="tutorial-stage-meta">
<span class="tutorial-pill tutorial-pill-accent" id="tutorialSource"><?= htmlspecialchars((string) $activeTutorial['source_label'], ENT_QUOTES, 'UTF-8') ?></span>
<span class="tutorial-pill" id="tutorialProvider"><?= htmlspecialchars((string) $activeTutorial['provider'], ENT_QUOTES, 'UTF-8') ?></span>
</div>
<div class="tutorial-stage-head">
<h2 class="tutorial-stage-title" id="tutorialTitle"><?= htmlspecialchars((string) $activeTutorial['name'], ENT_QUOTES, 'UTF-8') ?></h2>
<p class="tutorial-stage-description" id="tutorialDescription"><?= htmlspecialchars((string) $activeTutorial['description'], ENT_QUOTES, 'UTF-8') ?></p>
</div>
<div class="tutorial-stage-actions">
<a
class="tutorial-link<?= (string) $activeTutorial['open_url'] === '' ? ' is-disabled' : '' ?>"
id="tutorialOpenLink"
href="<?= htmlspecialchars((string) ($activeTutorial['open_url'] !== '' ? $activeTutorial['open_url'] : '#'), ENT_QUOTES, 'UTF-8') ?>"
<?= (string) $activeTutorial['open_url'] !== '' ? 'target="_blank" rel="noopener noreferrer"' : 'aria-disabled="true" tabindex="-1"' ?>
>
<?= (string) $activeTutorial['open_url'] !== '' ? 'Abrir fuente original' : 'Video pendiente' ?>
</a>
</div>
</div>
<div class="tutorial-viewer">
<div class="tutorial-viewer-frame" id="tutorialViewerFrame" aria-live="polite" aria-busy="false">
<?php if ((string) $activeTutorial['source_type'] === 'local'): ?>
<video class="tutorial-media" controls preload="metadata">
<source
src="<?= htmlspecialchars((string) $activeTutorial['embed_url'], ENT_QUOTES, 'UTF-8') ?>"
type="<?= htmlspecialchars((string) (($activeTutorial['source'] ?? [])['mime'] ?? 'video/mp4'), ENT_QUOTES, 'UTF-8') ?>"
/>
</video>
<?php elseif ((string) $activeTutorial['source_type'] === 'youtube'): ?>
<iframe
class="tutorial-media"
src="<?= htmlspecialchars((string) $activeTutorial['embed_url'], ENT_QUOTES, 'UTF-8') ?>"
title="Tutorial de <?= htmlspecialchars((string) $activeTutorial['name'], ENT_QUOTES, 'UTF-8') ?>"
loading="eager"
referrerpolicy="strict-origin-when-cross-origin"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
<?php else: ?>
<div class="tutorial-fallback">
<div>
<h3><?= htmlspecialchars((string) $activeTutorial['name'], ENT_QUOTES, 'UTF-8') ?></h3>
<p><?= htmlspecialchars((string) $activeTutorial['fallback_message'], ENT_QUOTES, 'UTF-8') ?></p>
</div>
</div>
<?php endif; ?>
</div>
<div class="tutorial-loader" id="tutorialLoader" aria-hidden="true">
<span></span>
<span></span>
<span></span>
</div>
</div>
</section>
</section>
<script id="tutorialsData" type="application/json"><?= $tutorialsJson ?: '[]' ?></script>
</main>
<?php include __DIR__ . '/includes/piepagina.php'; ?>
<script src="js/main.js" defer></script>
<script src="js/tutoriales.js" defer></script>
</body>
</html>