Календарь событий

Для того что бы у нас правильно отображались наши события, нужно получить их с базы данных. 

foreach ($result_services as $val):    

  $result[$key]['title'] = $val->title;

  $result[$key]['publish'] = $val->field_publish_value;

  $result[$key]['day'] = $val->field_day_value;

  $result[$key]['day_month'] = $val->field_num_month_value;

  $result[$key]['datepicker'] = $val->field_datepicker_value;

endforeach;

title - название события.

publish - может содержать только одно из значений:

  'one' - публикация только один раз.

  'month' - каждый месяц.

  'week' - каждую неделю.

day - номер дня в недели 1-это понедельник, 7-это воскресенье. (значение для еженедельной публикации)

day_month - число месяца без ведущего нуля. (значение для публикации "раз в месяц")

datepicker - дату в формате '2015-03-06 00:00:00' (значение для показа "один раз")

 

Это все что от вас требуется, для правильного отображения ваших событий. Дальше php генерирует еженедельные(например каждый понедельник) и ежемесячные(например девятого числа каждого месяца) события и выведет их в календарь.

Для заметки - массив дат для публикации должен иметь вот такое дерево:

$events[2015-3-30][]['title'] = 'название события'. Обратите внимание дата без ведущих нулей.

      

<?php

$EngDays = array("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday");    // для подстановки в strtotime()
    $EngMonths = array("January", "February", "March", "April", "May", "June", "July", "August",
        "September", "October", "November", "December");    // для подстановки в strtotime()

    if(isset($_GET['year'])and($_GET['month'])){    // проверяем какой месяц года вывести    
        $month = $_GET['month'];
        $year = $_GET['year'];        
    }else{                                                        // если не указан, выводим текущий
        $month = date("n");
        $year = date("Y");    
    }
    
    $events = array();
    foreach($result as $key => $value) {     // получаем даты для публикации        
        switch($value['publish']){
            case 'month':                                // публикация каждый месяц        
            $month_day = $value['day_month'];
            $xtime = date("Y-n-j",mktime(0, 0, 0, $month, $month_day,  $year));
            $events[$xtime][]['title'] = $value['title']; // накапливаем массив дат                           
            break;
            case 'one':                                 // публикация один раз
            $picker = explode(' ' ,$value['datepicker']);        
            $dateCreate = date_create($picker[0]);
            $xtime = date_format($dateCreate, 'Y-n-j');
            $events[$xtime][]['title'] = $value['title']; // накапливаем массив дат                       
            break;
        }            
        if ($value['publish'] == 'week'){         // публикация каждую неделю
            $value['day'] = $EngDays[$value['day'] - 1];
            $everyMonth = $EngMonths[$month - 1];    
            $firstDayMonth = date('j', strtotime('first ' . $value['day'] . ' of ' .$everyMonth . $year)); // получаем число первого заданного дня(например "понедельника") месяца
            $AllDayMonth = date('j', strtotime('last day of' .$everyMonth . $year)); // число дней в месяце
            
            for($i=1; $i<=5; $i++) {                // день больше пяти раз в месяц не бывает
                if($i<=4){                                // четыре раза в месяц, день всегда бывает            
                    $xtime = date("Y-n-j",mktime(0, 0, 0, $month, $firstDayMonth,  $year));
                    $events[$xtime][]['title'] = $value['title']; // накапливаем массив дат
                    $firstDayMonth += 7;
                }
                elseif((($firstDayMonth + 7)and($i==5)) <= $AllDayMonth){
                    $xtime = date("Y-n-j",mktime(0, 0, 0, $month, $firstDayMonth,  $year));
                    $events[$xtime][]['title'] = $value['title']; // накапливаем массив дат
                }
                    
            }
            
        }
        
    }
        
    /* draws a calendar */
    function draw_calendar($month,$year,$events = array()){
    
        // Дни недели
        $headings = array('Понедельник','Вторник','Среда','Четверг','Пятница','Суббота','Воскресенье');
            
        // Счетчик дней в неделе
        $running_day = date('w',mktime(0,0,0,$month,1,$year))-1;
        if ($running_day == -1) { $running_day = 6; }        
        // Количество дней в месяце
        $days_in_month = date('t',mktime(0,0,0,$month,1,$year));
        
        $calendar = '<table cellpadding="0" cellspacing="0" class="calendar">';        
        $calendar.= '<tr class="calendar-row"><td class="calendar-day-head">'.implode('</td><td class="calendar-day-head">',$headings).'</td></tr>';
        
        
        $calendar.= '<tr class="calendar-row">';

        /* Добавляем пустые ячейкм в первой неделе */
        for($x = 0; $x < $running_day; $x++): 
            $calendar.= '<td class="calendar-day-np">0&nbsp;</td>';
        endfor;
        /* keep going with days.... */        
        for($list_day = 1; $list_day <= $days_in_month; $list_day++):

            $calendar.= '<td class="calendar-day"><div style="position:relative;height:100px;">';
                $calendar.= '<div class="day-number">'.$list_day.'</div>';
                
                // Выводим все события за данное число
                $event_day = $year.'-'.$month.'-'.$list_day;
                if(isset($events[$event_day])) {
                    foreach($events[$event_day] as $event) {
                        $calendar.= '<div class="event ' .$event['publish']. '">'. $event['title'].'</div>';
                    }
                } 
                
            $calendar.= '</div></td>';
            
            // Если последний день в недели
            if($running_day == 6):
                $calendar.= '</tr>';
                // Если это не последний день в месяце
                if ($list_day != $days_in_month) {
                    $calendar.= '<tr class="calendar-row">';
                }
                $running_day = -1;
            endif;
            $running_day++;
            
        endfor;

        /* Заканчиваем дни в месяце */
        if($running_day < 7):
            for($x = 1; $x <= (7 - $running_day); $x++):
                $calendar.= '<td class="calendar-day-np">1&nbsp;</td>';
            endfor;
        endif;

        $calendar.= '</tr></table>';
        
        /* all done, return result */
        return $calendar;
    }

        
    /* select month control */
    $select_month_control = '<select name="month" id="month">';
    for($x = 1; $x <= 12; $x++) {
        $select_month_control.= '<option value="'.$x.'"'.($x != $month ? '' : ' selected="selected"').'>'.date('F',mktime(0,0,0,$x,1,$year)).'</option>';
    }
    $select_month_control.= '</select>';

    /* select year control */
    $year_range = 7;
    $select_year_control = '<select name="year" id="year">';
    for($x = ($year-floor($year_range/2)); $x <= ($year+floor($year_range/2)); $x++) {
        $select_year_control.= '<option value="'.$x.'"'.($x != $year ? '' : ' selected="selected"').'>'.$x.'</option>';
    }
    $select_year_control.= '</select>';

    /* "next month" control */
    $next_month_link = '<a href="?month='.($month != 12 ? $month + 1 : 1).'&year='.($month != 12 ? $year : $year + 1).'" class="control">Next Month &gt;&gt;</a>';

    /* "previous month" control */
    $previous_month_link = '<a href="?month='.($month != 1 ? $month - 1 : 12).'&year='.($month != 1 ? $year : $year - 1).'" class="control">&lt;&lt;     Previous Month</a>';

    /* bringing the controls together */
    $controls = '<form method="get">'.$select_month_control.$select_year_control .'&nbsp;<input type="submit" name="submit" value="Go" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$previous_month_link.'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$next_month_link.' </form>';

    

    echo '<h2 style="float:left; padding-right:30px;">'.date('F',mktime(0,0,0,$month,1,$year)).' '.$year.'</h2>';
    echo '<div style="float:left;">'.$controls.'</div>';
    echo '<div style="clear:both;"></div>';
    echo draw_calendar($month,$year,$events);
    echo '<br /><br />';
?>