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

Last change on this file since 1900 was 1900, checked in by rub, 17 years ago

Apply property svn:eol-style Value: LF

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