Календарь на PHP и Ajax

Пример календаря на PHP и Ajax с переключением месяцев. Можно использовать как заготовку для решения любых задач. Я использовал его для создания плагина календаря мероприятий на WordPress.
Скрипт использует процедурный подход, но имеет разделенную структуру с шаблоном , что довольно удобно. JMS University
Содержание
Файл /index.php
<?php
// Получить текущий год, месяц и день
list($iNowYear, $iNowMonth, $iNowDay) = explode('-', date('Y-m-d'));
// Получить текущий год и месяц в зависимости от возможных GET параметров
if (isset($_GET['month'])) {
list($iMonth, $iYear) = explode('-', $_GET['month']);
$iMonth = (int)$iMonth;
$iYear = (int)$iYear;
} else {
list($iMonth, $iYear) = explode('-', date('n-Y'));
}
// Получить название и количество дней указанного месяца
$iTimestamp = mktime(0, 0, 0, $iMonth, $iNowDay, $iYear);
list($sMonthName, $iDaysInMonth) = explode('-', date('F-t', $iTimestamp));
// Получить предыдущий год и месяц
$iPrevYear = $iYear;
$iPrevMonth = $iMonth - 1;
if ($iPrevMonth <= 0) {
$iPrevYear--;
$iPrevMonth = 12; // для декабря
}
// Получить следующий год и месяц
$iNextYear = $iYear;
$iNextMonth = $iMonth + 1;
if ($iNextMonth > 12) {
$iNextYear++;
$iNextMonth = 1;
}
// Получить количество дней предыдущего месяца
$iPrevDaysInMonth = (int)date('t', mktime(0, 0, 0, $iPrevMonth, $iNowDay, $iPrevYear));
// Получить числовое представление дня недели первого дня указанного (текущего) месяца
$iFirstDayDow = (int)date('w', mktime(0, 0, 0, $iMonth, 1, $iYear));
// В какой день начинается предыдущий месяц
$iPrevShowFrom = $iPrevDaysInMonth - $iFirstDayDow + 1;
// Если в предыдущем месяце
$bPreviousMonth = ($iFirstDayDow > 0);
// Начальный день
$iCurrentDay = ($bPreviousMonth) ? $iPrevShowFrom : 1;
$bNextMonth = false;
$sCalTblRows = '';
// Генерация строк для календаря
for ($i = 0; $i < 6; $i++) { // 6-недельный диапазон
$sCalTblRows .= '<tr>';
for ($j = 0; $j < 7; $j++) { // 7 дней в неделю
$sClass = '';
if ($iNowYear == $iYear && $iNowMonth == $iMonth && $iNowDay == $iCurrentDay && !$bPreviousMonth && !$bNextMonth) {
$sClass = 'today';
} elseif (!$bPreviousMonth && !$bNextMonth) {
$sClass = 'current';
}
$sCalTblRows .= '<td class="'.$sClass.'"><a href="javascript: void(0)">'.$iCurrentDay.'</a></td>';
// Следующий день
$iCurrentDay++;
if ($bPreviousMonth && $iCurrentDay > $iPrevDaysInMonth) {
$bPreviousMonth = false;
$iCurrentDay = 1;
}
if (!$bPreviousMonth && !$bNextMonth && $iCurrentDay > $iDaysInMonth) {
$bNextMonth = true;
$iCurrentDay = 1;
}
}
$sCalTblRows .= '</tr>';
}
// Подготовка замены ключей и генерация календаря
$aKeys = array(
'__prev_month__' => "{$iPrevMonth}-{$iPrevYear}",
'__next_month__' => "{$iNextMonth}-{$iNextYear}",
'__cal_caption__' => $sMonthName . ', ' . $iYear,
'__cal_rows__' => $sCalTblRows,
);
$sCalendarItself = strtr(file_get_contents('templates/calendar.html'), $aKeys);
// AJAX-запрос возвращающий календарь
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && isset($_GET['month'])) {
header('Content-Type: text/html; charset=utf-8');
echo $sCalendarItself;
exit;
}
$aVariables = array(
'__calendar__' => $sCalendarItself,
);
echo strtr(file_get_contents('templates/index.html'), $aVariables);Файл /templates/index.html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<meta name="author" content="Script Tutorials" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<title>Календарь на PHP и AJAX</title>
<!-- скрипты и стили -->
<link href="css/styles.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>
<body>
<header>
<h2>Календарь на PHP и AJAX</h2>
</header>
<div id="calendar">
__calendar__
</div>
</body>
</html>Файл /templates/calendar.html
<div class="navigation">
<a class="prev" href="index.php?month=__prev_month__" onclick="$('#calendar').load('index.php?month=__prev_month__&_r=' + Math.random()); return false;"></a>
<div class="title" >__cal_caption__</div>
<a class="next" href="index.php?month=__next_month__" onclick="$('#calendar').load('index.php?month=__next_month__&_r=' + Math.random()); return false;"></a>
</div>
<table>
<tr>
<th class="weekday">вс</th>
<th class="weekday">пн</th>
<th class="weekday">вт</th>
<th class="weekday">ср</th>
<th class="weekday">чт</th>
<th class="weekday">пт</th>
<th class="weekday">сб</th>
</tr>
__cal_rows__
</table>Файл /css/styles.css
* {
margin: 0;
padding: 0;
}
body {
background-color: #fff;
}
header {
background-color:rgba(33, 33, 33, 0.9);
color:#fff;
display:block;
font: 14px/1.3 Arial,sans-serif;
margin-bottom: 10px;
position:relative;
}
header h2{
font-size: 22px;
margin: 0px auto;
padding: 10px 0;
width: 80%;
text-align: center;
}
header a, a:visited {
text-decoration:none;
color:#fcfcfc;
}
/* стили календаря */
#calendar {
-moz-user-select: none;
border: 1px solid #EEEEEE;
border-radius: 6px 6px 6px 6px;
color: #333333;
font-family: Arial,sans-serif;
font-size: 1.1em;
margin: 10px auto;
padding: 0.4em;
width: 90%;
}
#calendar .navigation {
background-color: #565455;
border: 1px solid #c7c7c7;
border-radius: 6px 6px 6px 6px;
color: #FFFFFF;
font-weight: bold;
padding: 1px;
position: relative;
}
#calendar .navigation .title {
background: none repeat scroll 0 0 transparent;
border-color: rgba(0, 0, 0, 0);
color: inherit;
line-height: 1.8em;
margin: 0 2.3em;
text-align: center;
}
#calendar .navigation .prev, #calendar .navigation .next {
background-image: url(../images/nav.png);
height: 24px;
opacity: 0.9;
position: absolute;
top: 4px;
width: 24px;
}
#calendar .navigation .prev {
background-position: 0 0;
left: 4px;
}
#calendar .navigation .next {
background-position: -24px 0;
right: 4px;
}
#calendar .navigation .prev:hover, #calendar .navigation .next:hover {
opacity: 1;
}
#calendar table {
border-collapse: collapse;
font-size: 0.9em;
table-layout: fixed;
width: 100%;
}
#calendar table th {
border: 0 none;
font-weight: bold;
padding: 0.7em 0.3em;
text-align: center;
}
#calendar table td {
border: 0 none;
padding: 1px;
}
#calendar table td a {
background-color: #EEEEEE;
border: 1px solid #D8DCDF;
color: #004276;
display: block;
font-weight: normal;
opacity: 0.7;
padding: 0.2em;
text-align: right;
text-decoration: none;
}
#calendar table td a:hover {
background-color: #F6F6F6;
border: 1px solid #CDD5DA;
color: #111111;
}
#calendar table td.current a {
font-weight: bold;
opacity: 1;
}
#calendar table td.today a {
background-color: #FBF8EE;
border: 1px solid #FCD3A1;
color: #444444;
font-weight: bold;
opacity: 1;
}Чтобы первый день недели был не воскресенье, а понедельник, нужно найти строку:$iFirstDayDow = (int)date('w', mktime(0, 0, 0, $iMonth, 1, $iYear));
и после неё добавить:$iFirstDayDow = $iFirstDayDow - 1;
if($iFirstDayDow == -1) {
$iFirstDayDow = 6;
}


Добавить комментарий