Files
MYSOPHAL/front/newsletter.php
2025-11-09 10:02:18 +01:00

237 lines
5.3 KiB
PHP

<?php
require_once('../lib/tcpdf/templates/tcpdf_include.php');
include ('../model_controller/articles.list.php');
Session::checkLoginUser();
// --- Get Newsletter by ID ---
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
Html::redirect($CFG_GLPI["root_doc"] . "/front/newsletter.list.php");
exit;
}
$newsletter_id = (int) $_GET['id'];
global $DB;
$stmt = $DB->prepare("SELECT * FROM glpi_newsletters WHERE id = ? AND archived = 0");
$stmt->bind_param("i", $newsletter_id);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
Html::redirect($CFG_GLPI["root_doc"] . "/front/newsletter.list.php");
exit;
}
$newsletter = $result->fetch_assoc();
// Path stored in DB
$path = $newsletter['path']; // e.g. "N1" or "N2" or folder name
$title = $newsletter['title'];
// ---------------------- Flipbook rendering ----------------------
echo "<h2 style='text-align:center;margin:20px 0;color:#27548A;'>".$title."</h2>";
$files = scandir('../file_upload/newsletter/'.$path);
$count = sizeof($files);
echo '<div class="book">';
$i = 2; // skip . and ..
while ($i < $count) {
echo '
<div class="page">
<div class="front">
<img src="'.$CFG_GLPI['root_doc'].'/file_upload/newsletter/'.$path.'/'.$files[$i].'" alt="Img '.($i).'">
</div>';
if ($count % 2 != 0 && $i+2 > $count) {
echo '
<div class="back">
<img src="'.$CFG_GLPI['root_doc'].'/file_upload/newsletter/'.$path.'/'.$files[2].'" alt="Img 2">
</div>
</div>';
} else {
echo '
<div class="back">
<img src="'.$CFG_GLPI['root_doc'].'/file_upload/newsletter/'.$path.'/'.$files[$i+1].'" alt="Img '.($i+1).'">
</div>
</div>';
}
if ($count % 2 == 0 && $i+2 >= $count) {
echo '
<div class="page">
<div class="front"></div>
<div class="back">
<img src="'.$CFG_GLPI['root_doc'].'/file_upload/newsletter/'.$path.'/'.$files[2].'" alt="Img 2">
</div>
</div>';
}
$i += 2;
}
echo '</div>';
?>
<script>
const flipBook = (elBook) => {
elBook.style.setProperty("--c", 0);
elBook.querySelectorAll(".page").forEach((page, idx) => {
page.style.setProperty("--i", idx);
page.addEventListener("click", (evt) => {
if (evt.target.closest("a")) return;
const curr = evt.target.closest(".back") ? idx : idx + 1;
elBook.style.setProperty("--c", curr);
});
});
};
document.querySelectorAll(".book").forEach(flipBook);
</script>
<style>
* {
box-sizing: border-box;
}
/* FlipBook */
body {
/* or any other parent wrapper */
margin: 0;
display: flex;
min-height: 100dvh;
perspective: 1000px;
font: 1em/1.4 "Poppins", sans-serif;
overflow: hidden;
color: hsl(180 68% 5%);
background-image: radial-gradient(
circle farthest-corner at 50% 50%,
hsl(187 20% 88%) 30%,
hsl(149 20% 94%) 100%
);
}
.book {
position: relative;
display: flex;
margin: auto;
width: 65cqmin;
/*1* let pointer event go trough pages of lower Z than .book */
pointer-events: none;
transform-style: preserve-3d;
transition: translate 1s;
translate: calc(min(var(--c), 1) * 50%) 0%;
/* Incline on the X axis for pages preview */
rotate: 1 0 0 20deg;
}
.page {
/* PS: Don't go below thickness 0.5 or the pages might transpare */
--thickness: 4;
flex: none;
display: flex;
width: 100%;
font-size: 2cqmin;
/*1* allow pointer events on pages */
pointer-events: all;
user-select: none;
transform-style: preserve-3d;
transform-origin: left center;
transition: transform 1s,
rotate 1s ease-in
calc((min(var(--i), var(--c)) - max(var(--i), var(--c))) * 50ms);
translate: calc(var(--i) * -100%) 0px 0px;
transform: translateZ(
calc((var(--c) - var(--i) - 0.5) * calc(var(--thickness) * 0.23cqmin))
);
rotate: 0 1 0 calc(clamp(0, var(--c) - var(--i), 1) * -180deg);
}
.front,
.back {
position: relative;
flex: none;
width: 100%;
backface-visibility: hidden;
overflow: hidden;
background-color: #fff;
/* Fix backface visibility Firefox: */
translate: 0px;
}
.back {
translate: -100% 0;
rotate: 0 1 0 180deg;
}
/* That's it. Your FlipBook customization styles: */
.book {
counter-reset: page -1;
& a {
color: inherit;
}
}
.page {
box-shadow: 0em 0.5em 1em -0.2em #00000020;
}
.front,
.back {
display: flex;
flex-flow: column wrap;
justify-content: space-between;
padding: 2em;
border: 1px solid #0002;
&:has(img) {
padding: 0;
}
& img {
width: 100%;
height: 100%;
object-fit: cover;
}
&::after {
position: absolute;
bottom: 1em;
counter-increment: page;
//content: counter(page) ".";
font-size: 0.8em;
}
}
.cover {
&::after {
content: "";
}
}
.front {
&::after {
right: 1em;
}
background: linear-gradient(to left, #f7f7f7 80%, #eee 100%);
border-radius: 0.1em 0.5em 0.5em 0.1em;
}
.back {
&::after {
left: 1em;
}
background-image: linear-gradient(to right, #f7f7f7 80%, #eee 100%);
border-radius: 0.5em 0.1em 0.1em 0.5em;
}
.cover {
background: radial-gradient(
circle farthest-corner at 80% 20%,
hsl(150 80% 20% / 0.3) 0%,
hsl(170 60% 10% / 0.1) 100%
),
hsl(231, 32%, 29%) url("https://picsum.photos/id/984/800/900") 50% / cover;
color: hsl(200 30% 98%);
}
</style>