We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 39589
    • 7 Posts
    Hello,

    I need some help to display 3 months instead of one. I'm not good at php, i'm a designer. But i try hard.
    I don't even know where to start. Here the php code that generate the calendar :

    <?php
        class eventsCalendar2 {
        
            function __construct(modX &$modx,array $config = array()) {
                $this->modx =& $modx;
        
                $corePath = $this->modx->getOption('eventscalendar2.core_path',$config,$this->modx->getOption('core_path').'components/eventscalendar2/');
                $assetsUrl = $this->modx->getOption('eventscalendar2.assets_url',$config,$this->modx->getOption('assets_url').'components/eventscalendar2/');
                $connectorUrl = $assetsUrl.'connector.php';
        
                $this->config = array_merge(array(
                    'assetsUrl' => $assetsUrl,
                    'cssUrl' => $assetsUrl.'css/',
                    'jsUrl' => $assetsUrl.'js/',
                    'imagesUrl' => $assetsUrl.'images/',
        
                    'connectorUrl' => $connectorUrl,
        
                    'corePath' => $corePath,
                    'modelPath' => $corePath.'model/',
                    'chunksPath' => $corePath.'elements/chunks/',
                    'chunkSuffix' => '.chunk.tpl',
                    'snippetsPath' => $corePath.'elements/snippets/',
                    'processorsPath' => $corePath.'processors/',
                ),$config);
        
                //$this->modx->addPackage('eventscalendar2',$this->config['modelPath']);
                $this->modx->lexicon->load('eventscalendar2:default');
            }
        
            /**
             * Initializes eventsCalendar2 into different contexts.
             *
             * @access public
             * @param string $ctx The context to load. Defaults to web.
             */
            public function initialize($ctx = 'web') {
                switch ($ctx) {
                    case 'mgr':
                        if (!$this->modx->loadClass('eventscalendar2.request.eventsCalendar2ControllerRequest',$this->config['modelPath'],true,true)) {
                            return 'Could not load controller request handler.';
                        }
                        $this->request = new eventsCalendar2ControllerRequest($this);
                        return $this->request->handleRequest();
                    break;
                    case 'connector':
                        if (!$this->modx->loadClass('eventscalendar2.request.eventsCalendar2ConnectorRequest',$this->config['modelPath'],true,true)) {
                            return 'Could not load connector request handler.';
                        }
                        $this->request = new eventsCalendar2ConnectorRequest($this);
                        return $this->request->handle();
                    break;
                    default:
                        /* if you wanted to do any generic frontend stuff here.
                         * For example, if you have a lot of snippets but common code
                         * in them all at the beginning, you could put it here and just
                         * call $eventscalendar2->initialize($modx->context->get('key'));
                         * which would run this.
                         */
                    break;
                }
            }
        	
        	
        	/* Замеряет время выполнения функции
        	 * Вызывать в начале и конце скрипта
        	 *
        	 * */
        	function get_execution_time() {
        		static $microtime_start = null;
        		if($microtime_start === null)
        		{
        			$microtime_start = microtime(true);
        			return 0.0;
        		}
        		return microtime(true) - $microtime_start;
        	}
        	
        
        	/* Принимает массив элементов с ключами и выдает 2 массива - плейсхолдеры и значения
        	 * Можно использовать префиксы, вида 'lk'
        	 *
        	 * */
        	function makePlaceholders($arr, $prefix = '') {
        		if (!is_array($arr)) {return false;}
        		//if (!empty($prefix)) {$prefix .= '.';}
        
        		$res = array();
        		foreach ($arr as $k => $v) {
        			$res['pl'][$prefix.$k] = '[[+'.$prefix.$k.']]';
        			$res['vl'][$prefix.$k] = $v;
        		}
        		return $res;
        	}
        
        
        	/* Вывод ошибок
        	 * */
            function error($err) {
        		$error = 'eventsCalendar2 error: ' . $this->modx->lexicon($err);
        		$this->modx->log(modX::LOG_LEVEL_ERROR, $error);
        		if ($this->config['show_errors']) {
        			echo $error;
        		}
            }
        
        	/* Выводит календарь на заданный месяц и год
        	 * */
            function generateCalendar() {
                //Это сильно модефицированный календарь, оригинал - вот тут: http://www.softtime.ru/scripts/calendar.php          
        		$month = $this->config['month'];
        		$year = $this->config['year'];
                $time = mktime(0,0,0, $month, 1 ,$year);
                $dayofmonth = date('t', $time);     
                $day_count = 1;
                    // 1. Первая неделя
                    $num = 0;
                
                for ($i = 0; $i < 7; $i++) {
                    // Вычисляем номер дня недели для числа
                    $dayofweek = date('w', mktime(0, 0, 0, $month, $day_count, $year));
                
                    // Приводим к числа к формату 1 - понедельник, ..., 6 - суббота
                    if ($this->config['first_day'] == 1) {
                    $dayofweek = $dayofweek - 1;
                        if($dayofweek == -1) {$dayofweek = 6;}
                    }
                    
                    if($dayofweek == $i) {
                        // Если дни недели совпадают, заполняем массив $week числами месяца
                        $week[$num][$i] = $day_count;
                        $day_count++;
                    }
                    else {
                        $week[$num][$i] = '';
                    }
                }
                // 2. Последующие недели месяца
                while(true) {
                    $num++;
                
                    for($i = 0; $i < 7; $i++) {
                      $week[$num][$i] = $day_count;
                      $day_count++;
                      // Если достигли конца месяца - выходим из цикла
                      if($day_count > $dayofmonth) break;
                    }
                    // Если достигли конца месяца - выходим из цикла
                    if($day_count > $dayofmonth) break;
                }
                // 3. Выводим содержимое массива $week в виде календаря
        		$next_month = $month + 1; 
        		if ($next_month == 13) {$next_month = 1; $next_year = $year + 1;}
        		else {$next_year = $year;}
        		
        		$prev_month = $month - 1;
        		if ($prev_month == 0) {$prev_month = 12; $prev_year = $year - 1;}
        		else {$prev_year = $year;}
                
        		// Если указана json строка с массивом дат - пытаемся исмользовать ее
        		if (!empty($this->config['events'])) {
        			$events = @json_decode($this->config['events'], true);
        			if (!is_array($events)) {
        				$this->error('err_decode_events');
        			}
        		}
        		// Если нет - штатно получаем события
        		else {
        			$events = $this->getEvents($month, $year);
        		}
        		
        		// Украшаем полученные события
        		$tmp = $this->templateEvents($events);
        		$events = $tmp['events'];
        		$total = $tmp['total'];
    
        		
        		// Рисуем календарь
        		$month_name = $this->modx->lexicon('month'.$month);
        		$self = $this->modx->makeUrl($this->modx->resource->id);
        
        		$table = '<table class="'.$this->config['class_calendar'].'">';
        		$thead = array();
        		$thead['class_prev'] = $this->config['class_prev'];
        		$thead['class_month'] = $this->config['class_month'];
        		$thead['class_next'] = $this->config['class_next'];
        		$thead['link_prev'] = $self.'?action=refreshCalendar&month='.$prev_month.'&year='.$prev_year;
        		$thead['link_next'] = $self.'?action=refreshCalendar&month='.$next_month.'&year='.$next_year;
        		$thead['month_prev'] = $this->modx->lexicon('month'.$prev_month);
        		$thead['month_next'] = $this->modx->lexicon('month'.$next_month);
        		$thead['btn_prev'] = $this->config['btn_prev'];
        		$thead['btn_next'] = $this->config['btn_next'];
        		$thead['month_name'] = $month_name;
        		$thead['year'] = $year;
        		$pl = $this->makePlaceholders($thead, $this->config['plPrefix']);
        		$table .= $this->modx->getChunk($this->config['tplHead'], $pl['vl']);
        
                $table .= '<tr>';
        		// Обработка первого дня недели
        		if ($this->config['first_day'] == '0') {
        			 $table .= '<th class="'.$this->config['class_dow'].'">'.$this->modx->lexicon('day7').'</th>';
        			 $wend = 6;
        		} else {$wend = 7;}
        		
        		for ($i = 1; $i <= $wend; $i++) {
                      $table .= '<th class="'.$this->config['class_dow'].'">'.$this->modx->lexicon('day'.$i).'</th>';
                }
        		
        		$today = !empty($_SESSION['calendar_date']) ? $_SESSION['calendar_date'] : strftime('%Y-%m-%d', time() + $this->config['time_shift']*60*60);
        
        		foreach($week as $v) {
        			$table .= "</tr><tr>";
        			for($i = 0; $i < 7; $i++) {
        				if(!empty($v[$i])) {
        				   
        					if (strlen($v[$i]) == 1) {$day = '0'.$v[$i];} else {$day = $v[$i];}
        					$date = $year.'-'.sprintf('%02u',$month).'-'.$day;
        					if (($wend == 7 && ($i == 5 || $i == 6)) || ($wend == 6 && ($i == 0 || $i == 6))) {
        					   $class = $this->config['class_weekend'];
        					}
        					else {
        					   $class = $this->config['class_workday'];
        					}
        
        					if ($date == $today) {$class .= ' '.$this->config['class_today'];}
        					if (!empty($events[$date])) {$class .= ' '.$this->config['class_isevent'];}
        					else {$class .= ' '.$this->config['class_noevent'];}
        
        					$trow = array();
        					$trow['class'] = $class;
        					$trow['cell_id'] = $this->config['calendar_id'].'_'.$v[$i];
        					$trow['day'] = $v[$i];
        					$trow['fulldate'] = "$year-$month-$v[$i]";
        					$trow['class_date'] = $this->config['class_date'];
        					$trow['class_event'] = $this->config['class_event'];
        					if (isset($total[$date])) {
        						$trow['events'] = $events[$date];
        						$trow['day_total'] = $total[$date];
        					}
        					else {
        						$trow['events'] = '';
        						$trow['day_total'] = '';
        					}
        					$pl = $this->makePlaceholders($trow, $this->config['plPrefix']);
        					$table .= $this->modx->getChunk($this->config['tplCell'], $pl['vl']);
        				}
        				else {$table .= '<td class="'.$this->config['class_emptyday'].'"> </td>';}
        			}
        		} 
        		$table .= '</tr></table>';
        		return $table;
        	}
        
        	/* Получение событий из БД, принимает месяц и год
        	 * */
            function getEvents($month = '', $year = '') {
                $id = $this->config['id'];
                if (empty($month)) {$month = date('m');}
                if (empty($year)) {$year = date('Y');}
        
        		// Узнаем ID потомков указанного контейнера. Если указаны родители - выбираем по ним
        		$tmp = array();
        		if ($this->config['parents']) {
        			$parents = explode(',', $this->config['parents']);
        			foreach ($parents as $v) {
        				$v = trim($v);
        				if (!empty($v)) {$tmp = array_merge($tmp, $this->modx->getChildIds($v));}
        			}
        		}
        		// Если родители не указаны - выбираем по ID
        		else {
        			$tmp = $this->modx->getChildIds($id);
        		}
        		
        		$query = $this->modx->newQuery('modResource');
        		if (count($tmp) > 0) {
        			$query->where(array(
        				'published' => true,
        				'deleted' => false,
        				'id:IN' => $tmp
        			));
        			// Не показывать скрытые в меню
        			if (empty($this->config['showHidden'])) {
        				$query->andCondition(array('hidemenu' => 0));
        			}
        			// Не показывать контейнеры
        			if (!empty($this->config['hideContainers'])) {
        				$query->andCondition(array('isfolder' => 0));
        			}
        		}
        		else {$this->error('no_result');} // У документа нет потомков - это ошибка
        		
        		// Если источником события задан TV параметр - работаем по нему
        		if (preg_match('/^tv/i', $this->config['dateSource'])) {
        			$this->isTV = 1;
        			$this->config['dateSource'] = preg_replace('/^tv/i', '', $this->config['dateSource']);
        		}
        		else {
        			// Улучшенная проверка на TV параметр
        			$tmp = $this->modx->newObject('modResource')->toArray();
        			if (!array_key_exists($this->config['dateSource'], $tmp)) {
        				$this->isTV = 1;
        			}
        			// Если не TV - значит поле контента
        			else {
        				$query->sortby($this->config['dateSource']);
        			}
        		}
        
        
        		// Извлекаем список ТВ, если он указан. Если не указан - извлечем позже
        		$templateVars = array();
        		if (!empty($this->config['includeTVs']) && !empty($this->config['includeTVList'])) {
        			$templateVars = $this->modx->getCollection('modTemplateVar', array('name:IN' => $this->config['includeTVList']));
        		}
        
        		
        		// Достаем данные из базы
        		// Извлекаем или нет поле content?
        		$fields = array_keys($this->modx->getFields('modResource'));
        		if (empty($this->config['includeContent'])) {
        			$fields = array_diff($fields, array('content'));
        		}
        		$columns = $this->config['includeContent'] ? $this->modx->getSelectColumns('modResource', 'modResource') : $this->modx->getSelectColumns('modResource', 'modResource', '', array('content'), true);
        		$query->select($columns);
        
        		$resources = $this->modx->getCollection('modResource', $query, false);
        		foreach ($resources as $resource) {
        			if ($this->isTV) {
        				$tv = $this->modx->getObject('modTemplateVar', array('name' => $this->config['dateSource']));
        				if (!empty($tv)) {
        					$date = $tv->getValue($resource->get('id'));
        				}
        				else {
        					$this->error('no_tv');
        					break;
        				}
        			}
        			else {
        				$date = $resource->get($this->config['dateSource']);
        			}
        
        			// Если ресурс подходит по дате - достаем (или нет) для него ТВ и сохраняем.
        			if (date('Y-n', strtotime($date)) == "$year-$month") {
        				$resource->set('date', $date);
        				
        				// Обработка ТВ, если нужно
        				$tvs = array();
        				if (!empty($this->config['includeTVs'])) {
        					// Если список нужных ТВ не был указан - извлекаем ВСЕ ТВ для ресурса
        					if (empty($this->config['includeTVList'])) {
        						$templateVars = $resource->getMany('TemplateVars');
        					}
        					// Обрабатываем ТВ
        					foreach ($templateVars as $tvId => $templateVar) {
        						if (!empty($this->config['includeTVList']) && !in_array($templateVar->get('name'), $this->config['includeTVList'])) {continue;}
        						// Рендерить ли ТВ?
        						// Да
        						if ($this->config['processTVs'] && (empty($this->config['processTVList']) || in_array($templateVar->get('name'), $this->config['processTVList']))) {
        							$tvs[$templateVar->get('name')] = $templateVar->renderOutput($resource->get('id'));
        						// Нет
        						} else {
        							$tvs[$templateVar->get('name')] = $templateVar->getValue($resource->get('id'));
        						}
        					}
        				}
        				
        				$content[] = array_merge($resource->toArray(), $tvs);
        			}
        		}
                return $content;
            }
        	
        	/* Оборачивание событий в чанк
        	 * */
        	function templateEvents($content = array()) {
        		$events = $total = array();
        		if (empty($content) || !is_array($content)) {$content = array();}
        		//  определяем переменные документа для подстановки в шаблон
        		foreach ($content as $v) {
        			$pl = array();
        			$date = strftime('%Y-%m-%d', strtotime($v['date']));
        			if (!isset($total[$date])) {$total[$date] = 0;}
        
        			//	Обязательные плейсхолдеры: урл, номер события и дата
        			if (!empty($v['id'])) {
        				$pl[$this->config['plPrefix'].'url'] = $this->modx->makeUrl($v['id']);;
        			}
        			$pl[$this->config['plPrefix'].'num'] = $total[$date] + 1;
        			$pl[$this->config['plPrefix'].'date'] = strftime($this->config['dateFormat'], strtotime($v['date']));
        				unset($v['date']);
        
        			foreach ($v as $k2 => $v2) {
        				$pl[$this->config['plPrefix'].$k2] = $v2;
        			}
        			$events[$date] .= $this->modx->getChunk($this->config['tplEvent'], $pl);
        			$total[$date] += 1;
        		}
        		//$events = preg_replace('/\[\[\+.*?\]\]/', '', $events);	// Вылезаем пустые плейсхолдеры
        		return array('events' => $events, 'total' => $total);
        	}
        
        	
        	/*  Обычная загрузка календаря при рендере страницы
        	 * */
        	function output() {
        		if (!empty($this->config['regCss'])) {
        			if (!empty($this->config['theme'])) {
        				$this->modx->regClientCSS('<link type="text/css" rel="stylesheet" href="'.$this->config['cssUrl'].$this->config['theme'].'/theme.css"/>');
        			}
        			else {
        				$this->modx->regClientCSS('<link type="text/css" rel="stylesheet" href="'.$this->config['cssUrl'].'default.css"/>');
        			}
        			
        		}
        		if (!empty($this->config['regJs'])) {
        			$this->modx->regClientStartupScript('<script type="text/javascript" src="'.$this->config['jsUrl'].'eventscalendar2.js"></script>');
        		}
        		
        		$calendar = $this->generateCalendar();
        		return $this->modx->getChunk($this->config['tplMain'], array($this->config['plPrefix'].'Calendar' => $calendar));
        	}
        	
        }


    If someone could help, it would be appreciate. Thank you.
      Eskem studio - Identitée visuelle & conception graphique pour PME et PM

      Création de site internet