Hi Killes

(first off, great work you're doing here!)

Right, I seem to be having problems with the 3rd Dec release of event-5.x-2.x-dev
Both the block and the page appear to be displaying 7months plus the current month. I've attached a screenshot showing both the calendar and the block.

I'm not sure but I think it might be in the function event_calendar_month in event.module (I keep seeing the use of the number 7, which I thought would be 7 days) - I'm still looking thru' this,

Cheers

Comments

fronbow’s picture

update:

I don't think the error is where I thought!

round about line 570 is this code, I changed the $x=8 to a break as this is the 'proper' php way of exiting a for loop!

while ($last_date['day'] > $cur_date['day']) {
   $week = 0;
    for ($x = $start; $x < 7; $x++) {
      $cur_day = (($week * 7) + ($x + 1) - $offset);
      $row[$x] = array(
        'class' => strtolower($weekdays[$x]['day']) . ' day-'. $cur_date['day'] . ($cur_date == $today ? ' today' : '') . ($cur_date['day'] == $day ? ' selected' : ''),
        'data' => $callback($cur_date, $view, $types, $terms));
      $cur_date = event_date_later($cur_date, 1);
      if ($cur_date['day'] > $last_date['day']) {
        //$x = 8;
        break;
      }
    }
    $week++;
    $start = 0;
    $tbody[] = array_pad($row, 7, array('class' => 'pad'));
    $row = array();
  }

After this while loop is executed, $week = 11;

I'm curious what the use of $week is for as I can't see it referenced anywhere, unless it's just for debugging.

Oh, and my mistake, it displays the following 8 months for some odd reason - I can't find anywhere in the settings that would suggest it's a config error??

cheers

fronbow’s picture

StatusFileSize
new1.42 KB

On further inspection, the check while ($last_date['day'] > $cur_date['day']) { kept going for some reason?

Here's my event_calendar_month function that works for my site.

<?php
function event_calendar_month($op, $date, $types = NULL, $terms = NULL, $rewrite_parameter = array()) {
  $year = $date['year'];
  $month = $date['month'];
  $day = $date['day'];

  switch ($op) {
    case 'page':
      // setup callback for data population
      $callback = 'event_render_day';
      $view = 'month';
      break;

    case 'block':
      // create caption and navigation links
      $caption = _event_nav($date, 'prev', 'block', $types, $terms) .' '. l(event_format_date($date, 'custom', t('F Y')), 'event/'. _event_format_url($date) .'/month') .' '. _event_nav($date, 'next', 'block', $types, $terms);

      $callback = 'event_render_day_single';
      $view = 'block';
      break;
  }

  event_calendar_data($date, $view, $types, $terms, 'prepopulate', array(), $rewrite_parameter);

  // get weekdays array and header information
  $weekdays = event_week_days();
  $thead = event_week_header();
  $tbody = array();

  // get GMT current date value
  $today = _event_user_date();

  // name of the month
  $month_name = event_format_date($date, 'custom', 'F');

  // date of first day of month
  $cur_date = $date;
  $cur_date['day'] = '01';

  // last day in month
  $last_date = $date;
  $last_date['day'] = date('t', mktime(0, 0, 0, $date['month'], 1, $date['year']));

  // pad the first week row array to fill up days in the previous month we don't build
  $row = array_fill(0, 6, array('class' => 'pad'));
  // get the day of week offset value for the first day of the month
  $start = $offset = _event_day_of_week($cur_date);
  
  $cur_date_check = (int) ($cur_date['year'].$cur_date['month'].$cur_date['day']);
  $last_date_check = (int) ($last_date['year'].$last_date['month'].$last_date['day']);
  // render the month calendar
  while ($last_date_check > $cur_date_check) {
   $week = 0;
    for ($x = $start; $x < 7; $x++) {
      $cur_day = (($week * 7) + ($x + 1) - $offset);
      $row[$x] = array(
        'class' => strtolower($weekdays[$x]['day']) . ' day-'. $cur_date['day'] . ($cur_date == $today ? ' today' : '') . ($cur_date['day'] == $day ? ' selected' : ''),
        'data' => $callback($cur_date, $view, $types, $terms));
      $cur_date = event_date_later($cur_date, 1);
      $cur_date_check = (int) ($cur_date['year'].$cur_date['month'].$cur_date['day']);
      $last_date_check = (int) ($last_date['year'].$last_date['month'].$last_date['day']);
      
      if ($cur_date_check > $last_date_check) {
        $x = 8;
      }
    }
    $week++;
    $start = 0;
    $tbody[] = array_pad($row, 7, array('class' => 'pad'));
    $row = array();
  }

  switch ($op) {
    case 'page':
      return array($thead, $tbody);
      break;
    case 'block':
      return theme('event_calendar_month', $op, $thead, $tbody, $attributes = array('class' => 'event-block '. strtolower($month_name)), $caption);
      break;
  }
}
?>

Rather than checking on single days, I'm checking the full date in ISO format (yyyymmdd)

HTH someone else

jtjones23’s picture

subscribing

flutedrumr’s picture

Status: Active » Needs review

woot, thanks fronbow. fixed the same issue i was having.

morbus iff’s picture

There's a simpler patch here -- a simpler > to >=. The while loop (while ($last_date['day'] > $cur_date['day'])) isn't checking the current day, but rather the first day of the current week. Once we're inside the week loop (for ($x = $start; $x < 7; $x++)), the $cur_date is increased by one ($cur_date = event_date_later($cur_date, 1);). However, this will eventually switch from (for example), "February 29" to "March 1" - $cur_date['day'] now equals 1 which fails the next if check (if ($cur_date['day'] >= $last_date['day'])) -- the day 1 (of March 1) is less than day 29 (of February 29). As of today, right now, my calendar block is showing two months of duplicates. Why? Because, March has more days than Feburary. So, eventually, $cur_date contains "March 30" (while $last_date continues to contain February 29). But, since we're only checking on days, and not months, 30 eventually is more than 29, and the duplicate days stop. In essence, the NUMBER of duplicates you see is based on how many more months have to go by until the month in $cur_date has more days than the month in $last_date. This is why fronbow's fix works - he's comparing months too, not just days.

The root of this bug is caused by if ($cur_date['day'] > $last_date['day']). "February 29th" in current date will never be greater than "February 29th" in last date - we have to wait for a month that has more than 29 days. Switching these ifs to >= solved the problem for me.

Here's a debug spit that helped solve this:

last date inside while is 29 / cur date inside while is 01 / start offset is 4
cur date after later: 02
cur date after later: 03
cur date after later: 04
last date inside while is 29 / cur date inside while is 04 / start offset is 0
cur date after later: 05
cur date after later: 06
cur date after later: 07
cur date after later: 08
cur date after later: 09
cur date after later: 10
cur date after later: 11
last date inside while is 29 / cur date inside while is 11 / start offset is 0
cur date after later: 12
cur date after later: 13
cur date after later: 14
cur date after later: 15
cur date after later: 16
cur date after later: 17
cur date after later: 18
last date inside while is 29 / cur date inside while is 18 / start offset is 0
cur date after later: 19
cur date after later: 20
cur date after later: 21
cur date after later: 22
cur date after later: 23
cur date after later: 24
cur date after later: 25
last date inside while is 29 / cur date inside while is 25 / start offset is 0
cur date after later: 26
cur date after later: 27
cur date after later: 28
cur date after later: 29
cur date after later: 01
cur date after later: 02
cur date after later: 03
last date inside while is 29 / cur date inside while is 03 / start offset is 0
cur date after later: 04
cur date after later: 05
cur date after later: 06
cur date after later: 07
cur date after later: 08
cur date after later: 09
cur date after later: 10
last date inside while is 29 / cur date inside while is 10 / start offset is 0
cur date after later: 11
cur date after later: 12
cur date after later: 13
cur date after later: 14
cur date after later: 15
cur date after later: 16
cur date after later: 17
last date inside while is 29 / cur date inside while is 17 / start offset is 0
cur date after later: 18
cur date after later: 19
cur date after later: 20
cur date after later: 21
cur date after later: 22
cur date after later: 23
cur date after later: 24
last date inside while is 29 / cur date inside while is 24 / start offset is 0
cur date after later: 25
cur date after later: 26
cur date after later: 27
cur date after later: 28
cur date after later: 29
cur date after later: 30
cur date inside if is 30 / last date inside while is 29 / start offset is 0
x is now 8.

morbus iff’s picture

StatusFileSize
new330 bytes
killes@www.drop.org’s picture

Status: Needs review » Fixed

applied to both 5.2 and 6.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.