calendar storage
This commit is contained in:
+9
-1
@@ -137,7 +137,15 @@ require __DIR__ . '/header.php';
|
||||
<!-- PLANNING PRINCIPAL -->
|
||||
<!-- ===================================================================== -->
|
||||
<section class="pf-section">
|
||||
<h2>Planning par semaine</h2>
|
||||
<div class="fc-week-header">
|
||||
<h2>Planning hebdo</h2>
|
||||
<div class="fc-week-nav-controls">
|
||||
<button id="fc-prev-school-year" class="fc-nav-button">‹</button>
|
||||
<span id="fc-current-school-year-label"></span>
|
||||
<button id="fc-next-school-year" class="fc-nav-button">›</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pf-table-wrapper" id="planningTable-wrapper">
|
||||
<table id="planningHeaderTable" class="pf-table pf-table--compact">
|
||||
<colgroup>
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
// /modules/family-calendar/admin/generate-calendar-year.php
|
||||
require __DIR__ . '/../../../includes/db.php';
|
||||
|
||||
// S'assurer que PDO lève des exceptions en cas d'erreur
|
||||
if (isset($pdo) && $pdo instanceof PDO) {
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} else {
|
||||
die("Erreur : PDO non initialisé dans db.php");
|
||||
}
|
||||
|
||||
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
|
||||
if ($year < 2000 || $year > 2100) {
|
||||
die("Année invalide.");
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
|
||||
// On supprime d'abord les semaines de cette année calendaire
|
||||
$stmtDel = $pdo->prepare("DELETE FROM pf_calendar_weeks WHERE year = :year");
|
||||
$stmtDel->execute([':year' => $year]);
|
||||
|
||||
// 1er janvier de l'année calendaire
|
||||
$start = new DateTime("$year-01-01");
|
||||
|
||||
// On remonte au lundi précédent (ou on reste dessus si déjà lundi)
|
||||
while ($start->format('N') != 1) { // 1 = lundi
|
||||
$start->modify('-1 day');
|
||||
}
|
||||
|
||||
// Dernier jour de l'année
|
||||
$end = new DateTime("$year-12-31");
|
||||
|
||||
// Préparation de l'INSERT avec gestion des doublons
|
||||
// (en supposant une contrainte UNIQUE, par ex. sur (year, week_iso_year, week_iso_number))
|
||||
$sql = "
|
||||
INSERT INTO pf_calendar_weeks (
|
||||
year, week_iso_year, week_iso_number, week_label,
|
||||
month, month_name,
|
||||
week_start_date, mon_date, tue_date, wed_date, thu_date, fri_date, sat_date, sun_date
|
||||
) VALUES (
|
||||
:year, :week_iso_year, :week_iso_number, :week_label,
|
||||
:month, :month_name,
|
||||
:week_start_date, :mon_date, :tue_date, :wed_date, :thu_date, :fri_date, :sat_date, :sun_date
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
week_label = VALUES(week_label),
|
||||
month = VALUES(month),
|
||||
month_name = VALUES(month_name),
|
||||
week_start_date = VALUES(week_start_date),
|
||||
mon_date = VALUES(mon_date),
|
||||
tue_date = VALUES(tue_date),
|
||||
wed_date = VALUES(wed_date),
|
||||
thu_date = VALUES(thu_date),
|
||||
fri_date = VALUES(fri_date),
|
||||
sat_date = VALUES(sat_date),
|
||||
sun_date = VALUES(sun_date)
|
||||
";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
|
||||
// fonction mois FR
|
||||
function getMonthNameFr($monthIndexZeroBased) {
|
||||
$months = [
|
||||
"Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin",
|
||||
"Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre",
|
||||
];
|
||||
return $months[$monthIndexZeroBased] ?? "";
|
||||
}
|
||||
|
||||
$current = clone $start;
|
||||
$insertCount = 0;
|
||||
|
||||
while ($current <= $end) {
|
||||
$monday = clone $current;
|
||||
|
||||
// Calcul des 7 jours de la semaine
|
||||
$mon = clone $monday;
|
||||
$tue = (clone $monday)->modify('+1 day');
|
||||
$wed = (clone $monday)->modify('+2 days');
|
||||
$thu = (clone $monday)->modify('+3 days');
|
||||
$fri = (clone $monday)->modify('+4 days');
|
||||
$sat = (clone $monday)->modify('+5 days');
|
||||
$sun = (clone $monday)->modify('+6 days');
|
||||
|
||||
// Année / semaine ISO
|
||||
$weekIsoYear = (int)$monday->format('o'); // année ISO
|
||||
$weekIsoNumber = (int)$monday->format('W');
|
||||
$weekLabel = 'W' . str_pad($weekIsoNumber, 2, '0', STR_PAD_LEFT);
|
||||
|
||||
// Détermination du mois d'affectation de la semaine
|
||||
// -> on compte combien de jours de la semaine tombent dans chaque mois
|
||||
$days = [$mon, $tue, $wed, $thu, $fri, $sat, $sun];
|
||||
|
||||
// compteur mois => nb de jours (clé = numéro de mois 1..12)
|
||||
$monthCounts = [];
|
||||
|
||||
foreach ($days as $d) {
|
||||
$m = (int)$d->format('n'); // 1-12
|
||||
if (!isset($monthCounts[$m])) {
|
||||
$monthCounts[$m] = 0;
|
||||
}
|
||||
$monthCounts[$m]++;
|
||||
}
|
||||
|
||||
// On prend le mois ayant le plus de jours
|
||||
// (si égalité, le mois ayant la plus petite valeur numérique gagnera,
|
||||
// ce qui est raisonnable, mais on peut changer si besoin)
|
||||
$chosenMonth = null;
|
||||
$maxDays = -1;
|
||||
foreach ($monthCounts as $m => $count) {
|
||||
if ($count > $maxDays) {
|
||||
$maxDays = $count;
|
||||
$chosenMonth = $m;
|
||||
}
|
||||
}
|
||||
|
||||
$month = $chosenMonth;
|
||||
$monthName = getMonthNameFr($month - 1);
|
||||
|
||||
$stmt->execute([
|
||||
':year' => $weekIsoYear, // <-- au lieu de $year
|
||||
':week_iso_year' => $weekIsoYear,
|
||||
':week_iso_number' => $weekIsoNumber,
|
||||
':week_label' => $weekLabel,
|
||||
':month' => $month,
|
||||
':month_name' => $monthName,
|
||||
':week_start_date' => $monday->format('Y-m-d'),
|
||||
':mon_date' => $mon->format('Y-m-d'),
|
||||
':tue_date' => $tue->format('Y-m-d'),
|
||||
':wed_date' => $wed->format('Y-m-d'),
|
||||
':thu_date' => $thu->format('Y-m-d'),
|
||||
':fri_date' => $fri->format('Y-m-d'),
|
||||
':sat_date' => $sat->format('Y-m-d'),
|
||||
':sun_date' => $sun->format('Y-m-d'),
|
||||
]);
|
||||
|
||||
|
||||
$insertCount++;
|
||||
$current->modify('+7 days');
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
|
||||
echo "Calendrier $year généré. Semaines traitées : " . $insertCount;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
die("Erreur PDO : " . $e->getMessage());
|
||||
} catch (Exception $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
die("Erreur générale : " . $e->getMessage());
|
||||
}
|
||||
@@ -92,8 +92,34 @@
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* Header du planning hebdo : même esprit que fc-month-header */
|
||||
.fc-week-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
padding-bottom: 8px;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.fc-week-nav-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
#fc-current-school-year-label {
|
||||
font-weight: 600;
|
||||
color: #243b53;
|
||||
}
|
||||
|
||||
#fc-current-school-year-label {
|
||||
font-weight: 600;
|
||||
color: #243b53;
|
||||
}
|
||||
|
||||
#planningTable-wrapper {
|
||||
max-height: 500px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
|
||||
@@ -19,15 +19,11 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
this.monthSelectionMenu = document.getElementById(
|
||||
"fc-month-selectionMenu"
|
||||
);
|
||||
// Initialiser avec septembre (mois 8, car 0-indexé) pour l'année scolaire
|
||||
|
||||
// Mois courant réel pour le calendrier mensuel
|
||||
this.currentMonth = new Date();
|
||||
const currentMonthIndex = this.currentMonth.getMonth();
|
||||
// Si on est avant septembre, on affiche l'année scolaire précédente
|
||||
if (currentMonthIndex < 8) {
|
||||
this.currentMonth.setFullYear(this.currentMonth.getFullYear() - 1);
|
||||
}
|
||||
this.currentMonth.setMonth(8); // Septembre
|
||||
this.currentMonth.setDate(1); // Premier jour du mois
|
||||
this.currentMonth.setDate(1); // premier jour du mois courant
|
||||
|
||||
this.viewMode = "1month"; // "1month", "2months", "year"
|
||||
|
||||
if (!this.planningBody || !this.selectionMenu) {
|
||||
@@ -52,7 +48,20 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
// ================== INIT ==================
|
||||
async init() {
|
||||
this.setupEventListeners();
|
||||
this.weeks = this.generateWeeksStructure();
|
||||
|
||||
// Déterminer l'année scolaire en cours à partir de la date du jour
|
||||
const now = new Date();
|
||||
const nowMonth = now.getMonth(); // 0-11
|
||||
const nowYear = now.getFullYear();
|
||||
this.currentSchoolYearStart = nowMonth >= 8 ? nowYear : nowYear - 1;
|
||||
|
||||
// Charger les semaines pour l'année scolaire courante
|
||||
this.weeks = await this.fetchWeeksStructureScolaire(
|
||||
this.currentSchoolYearStart
|
||||
);
|
||||
|
||||
// Mettre à jour le label d'année scolaire dans l'UI
|
||||
this.updateSchoolYearLabel();
|
||||
|
||||
this.dbEvents = this.loadDbEvents();
|
||||
this.fixedEvents = await this.fetchPublicAndSchoolHolidays();
|
||||
@@ -211,47 +220,50 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
return [...publicHolidays, ...schoolHolidayEvents];
|
||||
}
|
||||
|
||||
generateWeeksStructure() {
|
||||
const weeks = [];
|
||||
const start = new Date(2025, 8, 1); // 1er septembre 2025
|
||||
const end = new Date(2026, 7, 31); // 31 août 2026
|
||||
let current = new Date(start);
|
||||
async fetchWeeksStructureScolaire(schoolYearStart) {
|
||||
try {
|
||||
const year = schoolYearStart || new Date().getFullYear();
|
||||
const res = await fetch(
|
||||
`/modules/family-calendar/includes/api/get-calendar-weeks-scolaire.php?school_year_start=${year}`
|
||||
);
|
||||
if (!res.ok) {
|
||||
throw new Error("Erreur HTTP " + res.status);
|
||||
}
|
||||
const data = await res.json();
|
||||
const weeks = data.weeks || [];
|
||||
|
||||
// Remonter au lundi le plus proche <= start
|
||||
while (current.getDay() !== 1) current.setDate(current.getDate() - 1);
|
||||
return weeks.map((w) => {
|
||||
const mon = new Date(w.mon_date + "T00:00:00");
|
||||
const tue = new Date(w.tue_date + "T00:00:00");
|
||||
const wed = new Date(w.wed_date + "T00:00:00");
|
||||
const thu = new Date(w.thu_date + "T00:00:00");
|
||||
const fri = new Date(w.fri_date + "T00:00:00");
|
||||
|
||||
while (current <= end) {
|
||||
const monday = new Date(current);
|
||||
|
||||
// C’est CETTE date qui doit servir de référence pour le mois
|
||||
const weekMonthDate = monday;
|
||||
|
||||
const weekData = {
|
||||
id: `${monday.getFullYear()}-W${getWeekOfYear(monday)}`,
|
||||
monthKey: `${weekMonthDate.getFullYear()}-${String(
|
||||
weekMonthDate.getMonth() + 1
|
||||
).padStart(2, "0")}`,
|
||||
monthName: getMonthNameFr(weekMonthDate.getMonth()),
|
||||
weekLabel: `W${getWeekOfYear(monday)}`,
|
||||
dayDates: {},
|
||||
dayFlags: {},
|
||||
};
|
||||
|
||||
["mon", "tue", "wed", "thu", "fri"].forEach((dayKey, index) => {
|
||||
const dayDate = new Date(monday);
|
||||
dayDate.setDate(monday.getDate() + index);
|
||||
weekData.dayDates[dayKey] = dayDate;
|
||||
weekData.dayFlags[dayKey] = { eventsOnDay: [] };
|
||||
return {
|
||||
id: `${w.week_iso_year}-W${w.week_iso_number}`, // ex: 2026-W01
|
||||
monthKey: `${w.year}-${String(w.month).padStart(2, "0")}`, // année calendaire + mois
|
||||
monthName: w.month_name,
|
||||
weekLabel: w.week_label,
|
||||
dayDates: {
|
||||
mon,
|
||||
tue,
|
||||
wed,
|
||||
thu,
|
||||
fri,
|
||||
},
|
||||
dayFlags: {
|
||||
mon: { eventsOnDay: [] },
|
||||
tue: { eventsOnDay: [] },
|
||||
wed: { eventsOnDay: [] },
|
||||
thu: { eventsOnDay: [] },
|
||||
fri: { eventsOnDay: [] },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
weeks.push(weekData);
|
||||
current.setDate(current.getDate() + 7);
|
||||
} catch (err) {
|
||||
console.error("Erreur chargement calendar weeks scolaire:", err);
|
||||
return [];
|
||||
}
|
||||
|
||||
// Juste pour verrouiller l’ordre si un jour tu modifies current ailleurs
|
||||
weeks.sort((a, b) => a.dayDates.mon - b.dayDates.mon);
|
||||
|
||||
return weeks;
|
||||
}
|
||||
|
||||
reprocessAndRender() {
|
||||
@@ -1032,6 +1044,20 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
nextBtn.addEventListener("click", () => this.navigateMonth(1));
|
||||
}
|
||||
|
||||
// Navigation année scolaire (planning hebdo)
|
||||
const prevSchoolYearBtn = document.getElementById("fc-prev-school-year");
|
||||
const nextSchoolYearBtn = document.getElementById("fc-next-school-year");
|
||||
if (prevSchoolYearBtn) {
|
||||
prevSchoolYearBtn.addEventListener("click", () =>
|
||||
this.changeSchoolYear(-1)
|
||||
);
|
||||
}
|
||||
if (nextSchoolYearBtn) {
|
||||
nextSchoolYearBtn.addEventListener("click", () =>
|
||||
this.changeSchoolYear(1)
|
||||
);
|
||||
}
|
||||
|
||||
// Boutons de changement de vue
|
||||
const viewButtons = document.querySelectorAll(".fc-view-button");
|
||||
viewButtons.forEach((btn) => {
|
||||
@@ -2501,24 +2527,28 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
btn.classList.add("fc-view-button--active");
|
||||
}
|
||||
});
|
||||
|
||||
// Si on passe en vue "year", caler currentMonth sur septembre
|
||||
if (mode === "year" && this.currentSchoolYearStart != null) {
|
||||
this.currentMonth = new Date(this.currentSchoolYearStart, 8, 1);
|
||||
}
|
||||
|
||||
this.renderMonthCalendar();
|
||||
}
|
||||
|
||||
navigateMonth(direction) {
|
||||
async navigateMonth(direction) {
|
||||
if (this.viewMode === "year") {
|
||||
// Navigation par année scolaire : on avance/recul d'un an,
|
||||
// en gardant currentMonth fixé sur septembre
|
||||
const year = this.currentMonth.getFullYear() + direction;
|
||||
this.currentMonth = new Date(year, 8, 1); // 8 = septembre
|
||||
} else {
|
||||
// Navigation simple par mois (1 ou 2 mois)
|
||||
const year = this.currentMonth.getFullYear();
|
||||
const month = this.currentMonth.getMonth() + direction;
|
||||
|
||||
// new Date gère automatiquement le dépassement (ex: 2025, 12 => jan 2026)
|
||||
this.currentMonth = new Date(year, month, 1);
|
||||
// Navigation par année scolaire via les flèches :
|
||||
// on réutilise changeSchoolYear
|
||||
await this.changeSchoolYear(direction);
|
||||
return;
|
||||
}
|
||||
|
||||
// Navigation simple par mois (1 ou 2 mois)
|
||||
const year = this.currentMonth.getFullYear();
|
||||
const month = this.currentMonth.getMonth() + direction;
|
||||
|
||||
this.currentMonth = new Date(year, month, 1);
|
||||
this.renderMonthCalendar();
|
||||
}
|
||||
|
||||
@@ -2563,6 +2593,35 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
}
|
||||
}
|
||||
|
||||
updateSchoolYearLabel() {
|
||||
const label = document.getElementById("fc-current-school-year-label");
|
||||
if (!label || this.currentSchoolYearStart == null) return;
|
||||
const start = this.currentSchoolYearStart;
|
||||
const end = start + 1;
|
||||
label.textContent = `Année scolaire ${start}–${end}`;
|
||||
}
|
||||
|
||||
async changeSchoolYear(delta) {
|
||||
// delta = -1 ou +1
|
||||
this.currentSchoolYearStart = (this.currentSchoolYearStart || 0) + delta;
|
||||
|
||||
// Mettre currentMonth sur septembre de cette nouvelle année pour la vue "year"
|
||||
// (pour le mensuel, on garde currentMonth tel quel, sauf si tu passes explicitement en vue year)
|
||||
if (this.viewMode === "year") {
|
||||
this.currentMonth = new Date(this.currentSchoolYearStart, 8, 1); // septembre
|
||||
}
|
||||
|
||||
// Recharger les semaines de cette année scolaire
|
||||
this.weeks = await this.fetchWeeksStructureScolaire(
|
||||
this.currentSchoolYearStart
|
||||
);
|
||||
|
||||
// Mettre à jour données / affichage
|
||||
this.reprocessAndRender();
|
||||
this.updateSchoolYearLabel();
|
||||
this.renderMonthCalendar();
|
||||
}
|
||||
|
||||
renderSingleMonthView() {
|
||||
const year = this.currentMonth.getFullYear();
|
||||
const month = this.currentMonth.getMonth();
|
||||
|
||||
@@ -24,3 +24,10 @@
|
||||
[2026-01-07T14:26:31+01:00] RAW INPUT: [{"date":"2025-09-08","type":"OFF_CAROLE","person":"Carole","duration":1}]
|
||||
[2026-01-07T14:26:36+01:00] RAW INPUT: [{"date":"2025-09-08","type":"OFF_CAROLE","person":"Carole","duration":1},{"date":"2025-09-09","type":"OFF_CAROLE","person":"Carole","duration":1}]
|
||||
[2026-01-07T14:30:24+01:00] RAW INPUT: [{"date":"2025-10-06","type":"CENTRE","duration":1},{"date":"2025-10-07","type":"CENTRE","duration":1}]
|
||||
[2026-01-08T09:21:34+01:00] RAW INPUT: [{"date":"2025-09-15","type":"EXTRA_OFF_CAROLE","person":"Carole","duration":1}]
|
||||
[2026-01-08T09:21:38+01:00] RAW INPUT: [{"date":"2025-09-17","type":"EXTRA_OFF_CAROLE","person":"Carole","duration":1}]
|
||||
[2026-01-08T09:21:58+01:00] RAW INPUT: [{"date":"2025-10-20","type":"CENTRE","duration":1},{"date":"2025-10-21","type":"CENTRE","duration":1},{"date":"2025-10-22","type":"CENTRE","duration":1},{"date":"2025-10-23","type":"CENTRE","duration":1},{"date":"2025-10-24","type":"CENTRE","duration":1}]
|
||||
[2026-01-08T09:22:43+01:00] RAW INPUT: [{"date":"2025-12-22","type":"EXTRA_OFF_CAROLE","person":"Carole","duration":1},{"date":"2025-12-23","type":"EXTRA_OFF_CAROLE","person":"Carole","duration":1},{"date":"2025-12-24","type":"EXTRA_OFF_CAROLE","person":"Carole","duration":1}]
|
||||
[2026-01-08T09:23:59+01:00] RAW INPUT: [{"date":"2025-12-22","type":"CENTRE","duration":1}]
|
||||
[2026-01-08T09:24:00+01:00] RAW INPUT: [{"date":"2025-12-23","type":"CENTRE","duration":1}]
|
||||
[2026-01-08T09:24:02+01:00] RAW INPUT: [{"date":"2025-12-24","type":"CENTRE","duration":1}]
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require __DIR__ . '/../../../../includes/db.php';
|
||||
|
||||
/**
|
||||
* Paramètre: school_year_start (optionnel)
|
||||
* - année de début d'année scolaire (ex: 2025 pour 09/2025 -> 08/2026)
|
||||
* - défaut: année courante si non fourni
|
||||
*/
|
||||
$schoolYearStart = isset($_GET['school_year_start'])
|
||||
? (int)$_GET['school_year_start']
|
||||
: (int)date('Y');
|
||||
|
||||
if ($schoolYearStart < 2000 || $schoolYearStart > 2100) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Année scolaire invalide.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$yearStart = $schoolYearStart;
|
||||
$yearEnd = $schoolYearStart + 1;
|
||||
|
||||
// On veut toutes les semaines:
|
||||
// - de septembre (month >= 9) de yearStart
|
||||
// - à août (month <= 8) de yearEnd
|
||||
|
||||
try {
|
||||
$sql = "
|
||||
SELECT
|
||||
year,
|
||||
week_iso_year,
|
||||
week_iso_number,
|
||||
week_label,
|
||||
month,
|
||||
month_name,
|
||||
week_start_date,
|
||||
mon_date,
|
||||
tue_date,
|
||||
wed_date,
|
||||
thu_date,
|
||||
fri_date
|
||||
FROM pf_calendar_weeks
|
||||
WHERE
|
||||
(year = :year_start AND month >= 9)
|
||||
OR (year = :year_end AND month <= 8)
|
||||
ORDER BY week_start_date ASC
|
||||
";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([
|
||||
':year_start' => $yearStart,
|
||||
':year_end' => $yearEnd,
|
||||
]);
|
||||
|
||||
$weeks = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'school_year' => $schoolYearStart,
|
||||
'weeks' => $weeks,
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require __DIR__ . '/../../../../includes/db.php';
|
||||
|
||||
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT
|
||||
year,
|
||||
week_iso_year,
|
||||
week_iso_number,
|
||||
week_label,
|
||||
month,
|
||||
month_name,
|
||||
week_start_date,
|
||||
mon_date,
|
||||
tue_date,
|
||||
wed_date,
|
||||
thu_date,
|
||||
fri_date
|
||||
FROM pf_calendar_weeks
|
||||
WHERE year = :year
|
||||
ORDER BY week_start_date ASC
|
||||
");
|
||||
$stmt->execute([':year' => $year]);
|
||||
$weeks = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo json_encode(['weeks' => $weeks]);
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
Reference in New Issue
Block a user