source: trunk/include/calendar_monthly.class.php @ 3037

Last change on this file since 3037 was 2299, checked in by plg, 16 years ago

Bug fixed: as rvelices notified me by email, my header replacement script was
bugged (r2297 was repeating new and old header).

By the way, I've also removed the replacement keywords. We were using them
because it was a common usage with CVS but it is advised not to use them with
Subversion. Personnaly, it is a problem when I search differences between 2
Piwigo installations outside Subversion.

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 14.5 KB
RevLine 
[1109]1<?php
[1055]2// +-----------------------------------------------------------------------+
[2297]3// | Piwigo - a PHP based picture gallery                                  |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
[1055]23
24include_once(PHPWG_ROOT_PATH.'include/calendar_base.class.php');
25
[1057]26define ('CYEAR',  0);
27define ('CMONTH', 1);
28define ('CDAY',   2);
29
[1055]30/**
31 * Monthly calendar style (composed of years/months and days)
32 */
33class Calendar extends CalendarBase
34{
35
[1059]36  /**
37   * Initialize the calendar
38   * @param string inner_sql used for queries (INNER JOIN or normal)
39   */
[1086]40  function initialize($inner_sql)
[1059]41  {
[1086]42    parent::initialize($inner_sql);
[1059]43    global $lang;
44    $this->calendar_levels = array(
45      array(
46          'sql'=> 'YEAR('.$this->date_field.')',
47          'labels' => null
48        ),
49      array(
50          'sql'=> 'MONTH('.$this->date_field.')',
51          'labels' => $lang['month']
52        ),
53      array(
54          'sql'=> 'DAYOFMONTH('.$this->date_field.')',
55          'labels' => null
56        ),
57     );
58  }
59
[1055]60/**
61 * Generate navigation bars for category page
62 * @return boolean false to indicate that thumbnails
63 * where not included here, true otherwise
64 */
[1086]65function generate_category_content()
[1055]66{
[1086]67  global $conf, $page;
[1055]68
[1090]69  $view_type = $page['chronology_view'];
[1057]70  if ($view_type==CAL_VIEW_CALENDAR)
71  {
[2231]72    global $template;
73    $tpl_var = array();
[1086]74    if ( count($page['chronology_date'])==0 )
[1057]75    {//case A: no year given - display all years+months
[2231]76      if ($this->build_global_calendar($tpl_var))
77      {
78        $template->assign('chronology_calendar', $tpl_var);
[1057]79        return true;
[2231]80      }
[1057]81    }
[1055]82
[1086]83    if ( count($page['chronology_date'])==1 )
[1057]84    {//case B: year given - display all days in given year
[2231]85      if ($this->build_year_calendar($tpl_var))
[1057]86      {
[2231]87        $template->assign('chronology_calendar', $tpl_var);
[1059]88        $this->build_nav_bar(CYEAR); // years
[1057]89        return true;
90      }
91    }
92
[1086]93    if ( count($page['chronology_date'])==2 )
[1057]94    {//case C: year+month given - display a nice month calendar
[2231]95      if ( $this->build_month_calendar($tpl_var) )
96      {
97        $template->assign('chronology_calendar', $tpl_var);
98      }
[1062]99      $this->build_next_prev();
[1055]100      return true;
101    }
102  }
103
[1086]104  if ($view_type==CAL_VIEW_LIST or count($page['chronology_date'])==3)
[1055]105  {
[1086]106    if ( count($page['chronology_date'])==0 )
[1057]107    {
[1059]108      $this->build_nav_bar(CYEAR); // years
[1057]109    }
[1086]110    if ( count($page['chronology_date'])==1)
[1057]111    {
[1059]112      $this->build_nav_bar(CMONTH); // month
[1057]113    }
[1086]114    if ( count($page['chronology_date'])==2 )
[1057]115    {
[1062]116      $day_labels = range( 1, $this->get_all_days_in_month(
[1086]117              $page['chronology_date'][CYEAR] ,$page['chronology_date'][CMONTH] ) );
[1062]118      array_unshift($day_labels, 0);
119      unset( $day_labels[0] );
120      $this->build_nav_bar( CDAY, $day_labels ); // days
[1057]121    }
[1062]122    $this->build_next_prev();
[1055]123  }
124  return false;
125}
126
127
128/**
129 * Returns a sql where subquery for the date field
130 * @param int max_levels return the where up to this level
131 * (e.g. 2=only year and month)
132 * @return string
133 */
[1057]134function get_date_where($max_levels=3)
[1055]135{
[1086]136  global $page;
137  $date = $page['chronology_date'];
[1057]138  while (count($date)>$max_levels)
[1055]139  {
[1057]140    array_pop($date);
[1055]141  }
142  $res = '';
[1069]143  if (isset($date[CYEAR]) and $date[CYEAR]!=='any')
[1055]144  {
[1057]145    $b = $date[CYEAR] . '-';
146    $e = $date[CYEAR] . '-';
[1069]147    if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
[1055]148    {
[1057]149      $b .= $date[CMONTH] . '-';
150      $e .= $date[CMONTH] . '-';
[1069]151      if (isset($date[CDAY]) and $date[CDAY]!=='any')
[1055]152      {
[1057]153        $b .= $date[CDAY];
154        $e .= $date[CDAY];
[1055]155      }
156      else
157      {
158        $b .= '01';
159        $e .= '31';
160      }
161    }
162    else
163    {
164      $b .= '01-01';
165      $e .= '12-31';
[1069]166      if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
[1055]167      {
[1059]168        $res .= ' AND '.$this->calendar_levels[CMONTH]['sql'].'='.$date[CMONTH];
[1055]169      }
[1069]170      if (isset($date[CDAY]) and $date[CDAY]!=='any')
[1055]171      {
[1059]172        $res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
[1055]173      }
174    }
175    $res = " AND $this->date_field BETWEEN '$b' AND '$e 23:59:59'" . $res;
176  }
177  else
178  {
179    $res = ' AND '.$this->date_field.' IS NOT NULL';
[1069]180    if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
[1055]181    {
[1059]182      $res .= ' AND '.$this->calendar_levels[CMONTH]['sql'].'='.$date[CMONTH];
[1055]183    }
[1069]184    if (isset($date[CDAY]) and $date[CDAY]!=='any')
[1055]185    {
[1059]186      $res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
[1055]187    }
188  }
189  return $res;
190}
191
[1057]192
[1059]193
194//--------------------------------------------------------- private members ---
195
196// returns an array with alll the days in a given month
197function get_all_days_in_month($year, $month)
[1057]198{
[1059]199  $md= array(1=>31,28,31,30,31,30,31,31,30,31,30,31);
200
201  if ( is_numeric($year) and $month==2)
[1057]202  {
[1059]203    $nb_days = $md[2];
204    if ( ($year%4==0)  and ( ($year%100!=0) or ($year%400!=0) ) )
205    {
206      $nb_days++;
207    }
[1057]208  }
[1059]209  elseif ( is_numeric($month) )
[1057]210  {
[1059]211    $nb_days = $md[ $month ];
[1057]212  }
[1059]213  else
[1057]214  {
[1059]215    $nb_days = 31;
[1057]216  }
[1061]217  return $nb_days;
[1057]218}
219
[2231]220function build_global_calendar(&$tpl_var)
[1055]221{
[1086]222  global $page;
223  assert( count($page['chronology_date']) == 0 );
[1055]224  $query='SELECT DISTINCT(DATE_FORMAT('.$this->date_field.',"%Y%m")) as period,
[1059]225            COUNT( DISTINCT(id) ) as count';
[1055]226  $query.= $this->inner_sql;
[1057]227  $query.= $this->get_date_where();
[1055]228  $query.= '
[1069]229  GROUP BY period
[1092]230  ORDER BY YEAR('.$this->date_field.') DESC, MONTH('.$this->date_field.')';
[1055]231
232  $result = pwg_query($query);
[1059]233  $items=array();
[1055]234  while ($row = mysql_fetch_array($result))
235  {
236    $y = substr($row['period'], 0, 4);
237    $m = (int)substr($row['period'], 4, 2);
238    if ( ! isset($items[$y]) )
239    {
240      $items[$y] = array('nb_images'=>0, 'children'=>array() );
241    }
242    $items[$y]['children'][$m] = $row['count'];
243    $items[$y]['nb_images'] += $row['count'];
244  }
245  //echo ('<pre>'. var_export($items, true) . '</pre>');
246  if (count($items)==1)
247  {// only one year exists so bail out to year view
248    list($y) = array_keys($items);
[1086]249    $page['chronology_date'][CYEAR] = $y;
[1055]250    return false;
251  }
252
[2231]253  global $lang;
[1055]254  foreach ( $items as $year=>$year_data)
255  {
[1086]256    $chronology_date = array( $year );
257    $url = duplicate_index_url( array('chronology_date'=>$chronology_date) );
[1055]258
[2231]259    $nav_bar = $this->get_nav_bar_from_items( $chronology_date,
[2101]260            $year_data['children'], 'calCal', false, false, $lang['month'] );
[1055]261
[2231]262    $tpl_var['calendar_bars'][] =
263      array(
264        'U_HEAD'  => $url,
265        'NB_IMAGES' => $year_data['nb_images'],
266        'HEAD_LABEL' => $year,
267        'NAV_BAR' => $nav_bar,
268      );
[1055]269  }
270  return true;
271}
272
[2231]273function build_year_calendar(&$tpl_var)
[1055]274{
[1086]275  global $page;
276  assert( count($page['chronology_date']) == 1 );
[1055]277  $query='SELECT DISTINCT(DATE_FORMAT('.$this->date_field.',"%m%d")) as period,
[1059]278            COUNT( DISTINCT(id) ) as count';
[1055]279  $query.= $this->inner_sql;
[1057]280  $query.= $this->get_date_where();
[1055]281  $query.= '
282  GROUP BY period';
283
284  $result = pwg_query($query);
[1059]285  $items=array();
[1055]286  while ($row = mysql_fetch_array($result))
287  {
288    $m = (int)substr($row['period'], 0, 2);
289    $d = substr($row['period'], 2, 2);
290    if ( ! isset($items[$m]) )
291    {
292      $items[$m] = array('nb_images'=>0, 'children'=>array() );
293    }
294    $items[$m]['children'][$d] = $row['count'];
295    $items[$m]['nb_images'] += $row['count'];
296  }
297  if (count($items)==1)
298  { // only one month exists so bail out to month view
299    list($m) = array_keys($items);
[1086]300    $page['chronology_date'][CMONTH] = $m;
[1055]301    return false;
302  }
[2231]303  global $lang;
[1055]304  foreach ( $items as $month=>$month_data)
305  {
[1086]306    $chronology_date = array( $page['chronology_date'][CYEAR], $month );
307    $url = duplicate_index_url( array('chronology_date'=>$chronology_date) );
[1055]308
[2231]309    $nav_bar = $this->get_nav_bar_from_items( $chronology_date,
[2101]310                     $month_data['children'], 'calCal', false );
[1055]311
[2231]312    $tpl_var['calendar_bars'][] =
313      array(
314        'U_HEAD'  => $url,
315        'NB_IMAGES' => $month_data['nb_images'],
316        'HEAD_LABEL' => $lang['month'][$month],
317        'NAV_BAR' => $nav_bar,
318      );
[1055]319  }
320  return true;
321
322}
323
[2231]324function build_month_calendar(&$tpl_var)
[1055]325{
[1086]326  global $page;
[1061]327  $query='SELECT DISTINCT(DAYOFMONTH('.$this->date_field.')) as period,
328            COUNT( DISTINCT(id) ) as count';
[1055]329  $query.= $this->inner_sql;
[1086]330  $query.= $this->get_date_where();
[1055]331  $query.= '
332  GROUP BY period';
333
[1558]334  $items=array();
[1055]335  $result = pwg_query($query);
336  while ($row = mysql_fetch_array($result))
337  {
[1061]338    $d = (int)$row['period'];
[1059]339    $items[$d] = array('nb_images'=>$row['count']);
[1055]340  }
341
[1059]342  foreach ( $items as $day=>$data)
[1055]343  {
[1086]344    $page['chronology_date'][CDAY]=$day;
[1055]345    $query = '
[1597]346SELECT id, file,tn_ext,path, width, height, DAYOFWEEK('.$this->date_field.')-1 as dow';
[1055]347    $query.= $this->inner_sql;
[1057]348    $query.= $this->get_date_where();
[1055]349    $query.= '
350  ORDER BY RAND()
351  LIMIT 0,1';
[1086]352    unset ( $page['chronology_date'][CDAY] );
[1055]353
[1597]354    $row = mysql_fetch_assoc(pwg_query($query));
355    $items[$day]['tn_url'] = get_thumbnail_url($row);
[1092]356    $items[$day]['file'] = $row['file'];
357    $items[$day]['path'] = $row['path'];
358    $items[$day]['tn_ext'] = @$row['tn_ext'];
[1061]359    $items[$day]['width'] = $row['width'];
360    $items[$day]['height'] = $row['height'];
361    $items[$day]['dow'] = $row['dow'];
[1059]362  }
[1055]363
[2231]364  global $lang, $conf;
[1061]365
366  if ( !empty($items)
367      and $conf['calendar_month_cell_width']>0
368      and $conf['calendar_month_cell_height']>0)
[1059]369  {
[1061]370    list($known_day) = array_keys($items);
371    $known_dow = $items[$known_day]['dow'];
372    $first_day_dow = ($known_dow-($known_day-1))%7;
373    if ($first_day_dow<0)
374    {
375      $first_day_dow += 7;
376    }
377    //first_day_dow = week day corresponding to the first day of this month
378    $wday_labels = $lang['day'];
[1055]379
[1061]380    // BEGIN - pass now in week starting Monday
381    if ($first_day_dow==0)
382    {
383      $first_day_dow = 6;
384    }
385    else
386    {
387      $first_day_dow -= 1;
388    }
389    array_push( $wday_labels, array_shift($wday_labels) );
390    // END - pass now in week starting Monday
[1059]391
[1061]392    $cell_width = $conf['calendar_month_cell_width'];
393    $cell_height = $conf['calendar_month_cell_height'];
394
[2231]395    $tpl_weeks    = array();
396    $tpl_crt_week = array();
[1061]397
398    //fill the empty days in the week before first day of this month
399    for ($i=0; $i<$first_day_dow; $i++)
400    {
[2231]401      $tpl_crt_week[] = array();
[1061]402    }
[2231]403
[1086]404    for ( $day = 1;
405          $day <= $this->get_all_days_in_month(
406            $page['chronology_date'][CYEAR], $page['chronology_date'][CMONTH]
407              );
408          $day++)
[1061]409    {
410      $dow = ($first_day_dow + $day-1)%7;
[1352]411      if ($dow==0 and $day!=1)
[1061]412      {
[2231]413        $tpl_weeks[]    = $tpl_crt_week; // add finished week to week list
414        $tpl_crt_week   = array(); // start new week
[1061]415      }
[2231]416
[1061]417      if ( !isset($items[$day]) )
[2231]418      {// empty day
419        $tpl_crt_week[]   =
420          array(
421              'DAY' => $day
422            );
[1061]423      }
424      else
425      {
[2231]426        $thumb = get_thumbnail_path($items[$day]);
427        $tn_size = @getimagesize($thumb);
428
[1061]429        $tn_width = $tn_size[0];
430        $tn_height = $tn_size[1];
431
432        // now need to fit the thumbnail of size tn_size within
433        // a cell of size cell_size by playing with CSS position (left/top)
434        // and the width and height of <img>.
435        $ratio_w = $tn_width/$cell_width;
436        $ratio_h = $tn_height/$cell_height;
437
[2231]438        $pos_top=$pos_left=0;
439        $css_style = '';
[1063]440
[1061]441        if ( $ratio_w>1 and $ratio_h>1)
442        {// cell completely smaller than the thumbnail so we will let the browser
443         // resize the thumbnail
444          if ($ratio_w > $ratio_h )
445          {// thumbnail ratio compared to cell -> wide format
[2231]446            $css_style = 'height:'.$cell_height.'px;';
[1061]447            $browser_img_width = $cell_height*$tn_width/$tn_height;
[1063]448            $pos_left = ($browser_img_width-$cell_width)/2;
[1061]449          }
450          else
451          {
[2231]452            $css_style = 'width:'.$cell_width.'px;';
[1061]453            $browser_img_height = $cell_width*$tn_height/$tn_width;
[1063]454            $pos_top = ($browser_img_height-$cell_height)/2;
[1061]455          }
456        }
457        else
458        {
459          $pos_left = ($tn_width-$cell_width)/2;
460          $pos_top = ($tn_height-$cell_height)/2;
461        }
462
463        if ( round($pos_left)!=0)
464        {
465          $css_style.='left:'.round(-$pos_left).'px;';
466        }
467        if ( round($pos_top)!=0)
468        {
469          $css_style.='top:'.round(-$pos_top).'px;';
470        }
[1086]471        $url = duplicate_index_url(
472            array(
473              'chronology_date' =>
474                array(
475                  $page['chronology_date'][CYEAR],
476                  $page['chronology_date'][CMONTH],
477                  $day
478                )
479            )
480          );
[2231]481
482        $tpl_crt_week[]   =
483          array(
[2265]484              'DAY'         => $day,
485              'DOW'         => $dow,
486              'NB_ELEMENTS' => $items[$day]['nb_images'],
487              'IMAGE'       => $items[$day]['tn_url'],
488              'U_IMG_LINK'  => $url,
489              'IMAGE_STYLE' => $css_style,
490              'IMAGE_ALT'   => $items[$day]['file'],
[1061]491            );
492      }
493    }
494    //fill the empty days in the week after the last day of this month
495    while ( $dow<6 )
496    {
[2231]497      $tpl_crt_week[] = array();
[1061]498      $dow++;
499    }
[2231]500    $tpl_weeks[]    = $tpl_crt_week;
[1059]501
[2231]502    $tpl_var['month_view'] =
503        array(
504           'CELL_WIDTH'   => $cell_width,
505           'CELL_HEIGHT' => $cell_height,
506           'wday_labels' => $wday_labels,
507           'weeks' => $tpl_weeks,
[1061]508          );
509  }
510
[1055]511  return true;
512}
513
514}
[2265]515?>
Note: See TracBrowser for help on using the repository browser.