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

Last change on this file since 30975 was 28926, checked in by mistic100, 10 years ago

bug 3002: Two classes with the same name : Calendar

  • Property svn:eol-style set to LF
File size: 14.1 KB
RevLine 
[1109]1<?php
[1055]2// +-----------------------------------------------------------------------+
[8728]3// | Piwigo - a PHP based photo gallery                                    |
[2297]4// +-----------------------------------------------------------------------+
[26461]5// | Copyright(C) 2008-2014 Piwigo Team                  http://piwigo.org |
[2297]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
[25507]24/**
25 * @package functions\calendar
26 */
27
[1055]28include_once(PHPWG_ROOT_PATH.'include/calendar_base.class.php');
29
[25507]30/** level of year view */
31define('CYEAR',  0);
32/** level of month view */
33define('CMONTH', 1);
34/** level of day view */
35define('CDAY',   2);
[1057]36
[25507]37
[1055]38/**
39 * Monthly calendar style (composed of years/months and days)
40 */
[28926]41class CalendarMonthly extends CalendarBase
[1055]42{
[1059]43  /**
[25507]44   * Initialize the calendar.
45   * @param string $inner_sql
[1059]46   */
[1086]47  function initialize($inner_sql)
[1059]48  {
[1086]49    parent::initialize($inner_sql);
[1059]50    global $lang;
51    $this->calendar_levels = array(
52      array(
[4398]53          'sql'=> pwg_db_get_year($this->date_field),
[1059]54          'labels' => null
55        ),
56      array(
[4398]57          'sql'=> pwg_db_get_month($this->date_field),
58          'labels' => $lang['month']
[1059]59        ),
60      array(
[4398]61          'sql'=> pwg_db_get_dayofmonth($this->date_field),
[1059]62          'labels' => null
63        ),
64     );
65  }
66
[25507]67  /**
68   * Generate navigation bars for category page.
69   *
70   * @return boolean false indicates that thumbnails where not included
71   */
72  function generate_category_content()
73  {
74    global $conf, $page;
[1055]75
[25507]76    $view_type = $page['chronology_view'];
77    if ($view_type==CAL_VIEW_CALENDAR)
78    {
79      global $template;
80      $tpl_var = array();
81      if ( count($page['chronology_date'])==0 )
82      {//case A: no year given - display all years+months
83        if ($this->build_global_calendar($tpl_var))
84        {
85          $template->assign('chronology_calendar', $tpl_var);
86          return true;
87        }
88      }
89
90      if ( count($page['chronology_date'])==1 )
91      {//case B: year given - display all days in given year
92        if ($this->build_year_calendar($tpl_var))
93        {
94          $template->assign('chronology_calendar', $tpl_var);
95          $this->build_nav_bar(CYEAR); // years
96          return true;
97        }
98      }
99
100      if ( count($page['chronology_date'])==2 )
101      {//case C: year+month given - display a nice month calendar
102        if ( $this->build_month_calendar($tpl_var) )
103        {
104          $template->assign('chronology_calendar', $tpl_var);
105        }
106        $this->build_next_prev();
[1057]107        return true;
[2231]108      }
[1057]109    }
[1055]110
[25507]111    if ($view_type==CAL_VIEW_LIST or count($page['chronology_date'])==3)
112    {
113      if ( count($page['chronology_date'])==0 )
[1057]114      {
[1059]115        $this->build_nav_bar(CYEAR); // years
[1057]116      }
[25507]117      if ( count($page['chronology_date'])==1)
[2231]118      {
[25507]119        $this->build_nav_bar(CMONTH); // month
[2231]120      }
[25507]121      if ( count($page['chronology_date'])==2 )
122      {
123        $day_labels = range( 1, $this->get_all_days_in_month(
124                $page['chronology_date'][CYEAR] ,$page['chronology_date'][CMONTH] ) );
125        array_unshift($day_labels, 0);
126        unset( $day_labels[0] );
127        $this->build_nav_bar( CDAY, $day_labels ); // days
128      }
[1062]129      $this->build_next_prev();
[1055]130    }
[25507]131    return false;
[1055]132  }
133
[25507]134  /**
135   * Returns a sql WHERE subquery for the date field.
136   *
137   * @param int $max_levels (e.g. 2=only year and month)
138   * @return string
139   */
140  function get_date_where($max_levels=3)
[1055]141  {
[25507]142    global $page;
143
144    $date = $page['chronology_date'];
145    while (count($date)>$max_levels)
[1057]146    {
[25507]147      array_pop($date);
[1057]148    }
[25507]149    $res = '';
150    if (isset($date[CYEAR]) and $date[CYEAR]!=='any')
[1057]151    {
[25507]152      $b = $date[CYEAR] . '-';
153      $e = $date[CYEAR] . '-';
154      if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
[1055]155      {
[25507]156        $b .= sprintf('%02d-', $date[CMONTH]);
157        $e .= sprintf('%02d-', $date[CMONTH]);
158        if (isset($date[CDAY]) and $date[CDAY]!=='any')
159        {
160          $b .= sprintf('%02d', $date[CDAY]);
161          $e .= sprintf('%02d', $date[CDAY]);
162        }
163        else
164        {
165          $b .= '01';
166          $e .= $this->get_all_days_in_month($date[CYEAR], $date[CMONTH]);
167        }
[1055]168      }
169      else
170      {
[25507]171        $b .= '01-01';
172        $e .= '12-31';
173        if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
174        {
175          $res .= ' AND '.$this->calendar_levels[CMONTH]['sql'].'='.$date[CMONTH];
176        }
177        if (isset($date[CDAY]) and $date[CDAY]!=='any')
178        {
179          $res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
180        }
[1055]181      }
[25507]182      $res = " AND $this->date_field BETWEEN '$b' AND '$e 23:59:59'" . $res;
[1055]183    }
184    else
185    {
[25507]186      $res = ' AND '.$this->date_field.' IS NOT NULL';
[1069]187      if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
[1055]188      {
[1059]189        $res .= ' AND '.$this->calendar_levels[CMONTH]['sql'].'='.$date[CMONTH];
[1055]190      }
[1069]191      if (isset($date[CDAY]) and $date[CDAY]!=='any')
[1055]192      {
[1059]193        $res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
[1055]194      }
195    }
[25507]196    return $res;
[1055]197  }
[25507]198
199  /**
200   * Returns an array with all the days in a given month.
201   *
202   * @param int $year
203   * @param int $month
204   * @return int[]
205   */
206  protected function get_all_days_in_month($year, $month)
[1055]207  {
[25507]208    $md= array(1=>31,28,31,30,31,30,31,31,30,31,30,31);
209
210    if ( is_numeric($year) and $month==2)
[1055]211    {
[25507]212      $nb_days = $md[2];
213      if ( ($year%4==0)  and ( ($year%100!=0) or ($year%400!=0) ) )
214      {
215        $nb_days++;
216      }
[1055]217    }
[25507]218    elseif ( is_numeric($month) )
[1055]219    {
[25507]220      $nb_days = $md[ $month ];
[1055]221    }
[25507]222    else
223    {
224      $nb_days = 31;
225    }
226    return $nb_days;
[1055]227  }
228
[25507]229  /**
230   * Build global calendar and assign the result in _$tpl_var_
231   *
232   * @param array $tpl_var
233   * @return bool
234   */
235  protected function build_global_calendar(&$tpl_var)
236  {
237    global $page;
[1057]238
[25507]239    assert( count($page['chronology_date']) == 0 );
240    $query='
241  SELECT '.pwg_db_get_date_YYYYMM($this->date_field).' as period,
242    COUNT(distinct id) as count';
243    $query.= $this->inner_sql;
244    $query.= $this->get_date_where();
245    $query.= '
246    GROUP BY period
247    ORDER BY '.pwg_db_get_year($this->date_field).' DESC, '.pwg_db_get_month($this->date_field).' ASC';
[1059]248
[25507]249    $result = pwg_query($query);
250    $items=array();
251    while ($row = pwg_db_fetch_assoc($result))
[1059]252    {
[25507]253      $y = substr($row['period'], 0, 4);
254      $m = (int)substr($row['period'], 4, 2);
255      if ( ! isset($items[$y]) )
256      {
257        $items[$y] = array('nb_images'=>0, 'children'=>array() );
258      }
259      $items[$y]['children'][$m] = $row['count'];
260      $items[$y]['nb_images'] += $row['count'];
[1059]261    }
[25507]262    //echo ('<pre>'. var_export($items, true) . '</pre>');
263    if (count($items)==1)
264    {// only one year exists so bail out to year view
265      list($y) = array_keys($items);
266      $page['chronology_date'][CYEAR] = $y;
267      return false;
268    }
[1057]269
[25507]270    global $lang;
271    foreach ( $items as $year=>$year_data)
272    {
273      $chronology_date = array( $year );
274      $url = duplicate_index_url( array('chronology_date'=>$chronology_date) );
[4398]275
[25507]276      $nav_bar = $this->get_nav_bar_from_items( $chronology_date,
277              $year_data['children'], false, false, $lang['month'] );
[1055]278
[25507]279      $tpl_var['calendar_bars'][] =
280        array(
281          'U_HEAD'  => $url,
282          'NB_IMAGES' => $year_data['nb_images'],
283          'HEAD_LABEL' => $year,
284          'items' => $nav_bar,
285        );
[1055]286    }
[25507]287
288    return true;
[1055]289  }
290
[25507]291  /**
292   * Build year calendar and assign the result in _$tpl_var_
293   *
294   * @param array $tpl_var
295   * @return bool
296   */
297  protected function build_year_calendar(&$tpl_var)
[1055]298  {
[25507]299    global $page;
[1055]300
[25507]301    assert( count($page['chronology_date']) == 1 );
302    $query='SELECT '.pwg_db_get_date_MMDD($this->date_field).' as period,
303              COUNT(DISTINCT id) as count';
304    $query.= $this->inner_sql;
305    $query.= $this->get_date_where();
306    $query.= '
307    GROUP BY period
308    ORDER BY period ASC';
[1055]309
[25507]310    $result = pwg_query($query);
311    $items=array();
312    while ($row = pwg_db_fetch_assoc($result))
313    {
314      $m = (int)substr($row['period'], 0, 2);
315      $d = substr($row['period'], 2, 2);
316      if ( ! isset($items[$m]) )
317      {
318        $items[$m] = array('nb_images'=>0, 'children'=>array() );
319      }
320      $items[$m]['children'][$d] = $row['count'];
321      $items[$m]['nb_images'] += $row['count'];
322    }
323    if (count($items)==1)
324    { // only one month exists so bail out to month view
325      list($m) = array_keys($items);
326      $page['chronology_date'][CMONTH] = $m;
327      return false;
328    }
329    global $lang;
330    foreach ( $items as $month=>$month_data)
331    {
332      $chronology_date = array( $page['chronology_date'][CYEAR], $month );
333      $url = duplicate_index_url( array('chronology_date'=>$chronology_date) );
[1055]334
[25507]335      $nav_bar = $this->get_nav_bar_from_items( $chronology_date,
336                       $month_data['children'], false );
[4398]337
[25507]338      $tpl_var['calendar_bars'][] =
339        array(
340          'U_HEAD'  => $url,
341          'NB_IMAGES' => $month_data['nb_images'],
342          'HEAD_LABEL' => $lang['month'][$month],
343          'items' => $nav_bar,
344        );
[1055]345    }
346
[25507]347    return true;
[1055]348  }
349
[25507]350  /**
351   * Build month calendar and assign the result in _$tpl_var_
352   *
353   * @param array $tpl_var
354   * @return bool
355   */
356  protected function build_month_calendar(&$tpl_var)
[1055]357  {
[25507]358    global $page, $lang, $conf;
[1055]359
[25507]360    $query='SELECT '.pwg_db_get_dayofmonth($this->date_field).' as period,
361              COUNT(DISTINCT id) as count';
[1055]362    $query.= $this->inner_sql;
[1057]363    $query.= $this->get_date_where();
[1055]364    $query.= '
[25507]365    GROUP BY period
366    ORDER BY period ASC';
[1055]367
[25507]368    $items=array();
369    $result = pwg_query($query);
370    while ($row = pwg_db_fetch_assoc($result))
371    {
372      $d = (int)$row['period'];
373      $items[$d] = array('nb_images'=>$row['count']);
374    }
[1055]375
[25507]376    foreach ( $items as $day=>$data)
[1061]377    {
[25507]378      $page['chronology_date'][CDAY]=$day;
379      $query = '
380  SELECT id, file,representative_ext,path,width,height,rotation, '.pwg_db_get_dayofweek($this->date_field).'-1 as dow';
381      $query.= $this->inner_sql;
382      $query.= $this->get_date_where();
383      $query.= '
384    ORDER BY '.DB_RANDOM_FUNCTION.'()
385    LIMIT 1';
386      unset ( $page['chronology_date'][CDAY] );
387
388      $row = pwg_db_fetch_assoc(pwg_query($query));
389      $derivative = new DerivativeImage(IMG_SQUARE, new SrcImage($row));
390      $items[$day]['derivative'] = $derivative;
391      $items[$day]['file'] = $row['file'];
392      $items[$day]['dow'] = $row['dow'];
[1061]393    }
[1055]394
[25507]395    if ( !empty($items) )
[1061]396    {
[25507]397      list($known_day) = array_keys($items);
398      $known_dow = $items[$known_day]['dow'];
399      $first_day_dow = ($known_dow-($known_day-1))%7;
400      if ($first_day_dow<0)
[12118]401      {
[25507]402        $first_day_dow += 7;
[12118]403      }
[25507]404      //first_day_dow = week day corresponding to the first day of this month
405      $wday_labels = $lang['day'];
406
407      if ('monday' == $conf['week_starts_on'])
[12118]408      {
[25507]409        if ($first_day_dow==0)
410        {
411          $first_day_dow = 6;
412        }
413        else
414        {
415          $first_day_dow -= 1;
416        }
417
418        $wday_labels[] = array_shift($wday_labels);
[12118]419      }
[8626]420
[25507]421      list($cell_width, $cell_height) = ImageStdParams::get_by_type(IMG_SQUARE)->sizing->ideal_size;
[1059]422
[25507]423      $tpl_weeks    = array();
424      $tpl_crt_week = array();
[1061]425
[25507]426      //fill the empty days in the week before first day of this month
427      for ($i=0; $i<$first_day_dow; $i++)
[1061]428      {
[25507]429        $tpl_crt_week[] = array();
[1061]430      }
[2231]431
[25507]432      for ( $day = 1;
433            $day <= $this->get_all_days_in_month(
434              $page['chronology_date'][CYEAR], $page['chronology_date'][CMONTH]
435                );
436            $day++)
[1061]437      {
[25507]438        $dow = ($first_day_dow + $day-1)%7;
439        if ($dow==0 and $day!=1)
440        {
441          $tpl_weeks[]    = $tpl_crt_week; // add finished week to week list
442          $tpl_crt_week   = array(); // start new week
443        }
[2231]444
[25507]445        if ( !isset($items[$day]) )
446        {// empty day
447          $tpl_crt_week[]   =
448            array(
449                'DAY' => $day
450              );
451        }
452        else
453        {
454          $url = duplicate_index_url(
455              array(
456                'chronology_date' =>
457                  array(
458                    $page['chronology_date'][CYEAR],
459                    $page['chronology_date'][CMONTH],
460                    $day
461                  )
462              )
463            );
464
465          $tpl_crt_week[]   =
466            array(
467                'DAY'         => $day,
468                'DOW'         => $dow,
469                'NB_ELEMENTS' => $items[$day]['nb_images'],
470                'IMAGE'       => $items[$day]['derivative']->get_url(),
471                'U_IMG_LINK'  => $url,
472                'IMAGE_ALT'   => $items[$day]['file'],
473              );
[1061]474        }
[25507]475      }
476      //fill the empty days in the week after the last day of this month
477      while ( $dow<6 )
478      {
479        $tpl_crt_week[] = array();
480        $dow++;
481      }
482      $tpl_weeks[]    = $tpl_crt_week;
[2231]483
[25507]484      $tpl_var['month_view'] =
[2231]485          array(
[25507]486             'CELL_WIDTH'   => $cell_width,
487             'CELL_HEIGHT' => $cell_height,
488             'wday_labels' => $wday_labels,
489             'weeks' => $tpl_weeks,
[1061]490            );
491    }
[1059]492
[25507]493    return true;
[1061]494  }
[1055]495}
496
[12118]497?>
Note: See TracBrowser for help on using the repository browser.