]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/CalendarList.php
applied mpullen patch (Revised to work on all date range combinations...),
[SourceForge/phpwiki.git] / lib / plugin / CalendarList.php
1 <?php // -*-php-*-
2 rcs_id('$Id: CalendarList.php,v 1.7 2005-07-21 18:55:55 rurban Exp $');
3
4 /**
5  Copyright 1999,2000,2001,2002,2005 $ThePhpWikiProgrammingTeam
6
7  This file is part of PhpWiki.
8
9  PhpWiki 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; either version 2 of the License, or
12  (at your option) any later version.
13
14  PhpWiki is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with PhpWiki; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 // if not defined in config.ini
25 if (!defined('SECONDS_PER_DAY'))                
26   define('SECONDS_PER_DAY',             24 * 3600);
27 if (!defined('SUBPAGE_SEPARATOR'))              
28   define('SUBPAGE_SEPARATOR',           "/");
29 if (!defined('PLUGIN_CALENDARLIST_ORDER'))      
30   define('PLUGIN_CALENDARLIST_ORDER',   'normal');
31 if (!defined('PLUGIN_CALENDARLIST_NEXT_N_DAYS'))
32   define('PLUGIN_CALENDARLIST_NEXT_N_DAYS','');
33 if (!defined('PLUGIN_CALENDARLIST_NEXT_N'))     
34   define('PLUGIN_CALENDARLIST_NEXT_N',   '');
35 if (!defined('PLUGIN_CALENDARLIST_LAST_N_DAYS'))
36   define('PLUGIN_CALENDARLIST_LAST_N_DAYS','');
37 if (!defined('PLUGIN_CALENDARLIST_LAST_N'))     
38   define('PLUGIN_CALENDARLIST_LAST_N',   '');
39
40 /**
41  * This is a list of calendar appointments. 
42  * Same arguments as Calendar, so no one is confused
43  * Uses <dl><dd>DATE<dt>page contents...
44  * Derived from Calendar.php by Martin Norbäck <martin@safelogic.se>
45  *
46  * Insert this plugin into your Calendar page, for example in:
47  *     WikiUser/Calendar
48  * Add the line: <?plugin CalendarList ?>
49  *
50  */
51 class WikiPlugin_CalendarList
52 extends WikiPlugin
53 {
54     function getName () {
55         return _("CalendarList");
56     }
57
58     function getDescription () {
59         return _("CalendarList");
60     }
61
62     function getDefaultArguments() {
63         return array('prefix'       => '[pagename]',
64                      'date_format'  => '%Y-%m-%d',
65                      'order'        => PLUGIN_CALENDARLIST_ORDER, // normal or reverse (report sequence)
66                      'year'         => '',
67                      'month'        => '',
68                      'month_offset' => 0,
69                      //support ranges: next n days/events
70                      'next_n_days'  => PLUGIN_CALENDARLIST_NEXT_N_DAYS, // one or the other, not both
71                      'next_n'       => PLUGIN_CALENDARLIST_NEXT_N,
72                      // last n days/entries:
73                      'last_n_days'  => PLUGIN_CALENDARLIST_LAST_N_DAYS, // one or the other, not both
74                      'last_n'       => PLUGIN_CALENDARLIST_LAST_N,
75
76                      'month_format' => '%B, %Y',
77                      'wday_format'  => '%a',
78                      'start_wday'   => '0');
79     }
80
81     /**
82      * return links (static only as of action=edit) 
83      *
84      * @param string $argstr The plugin argument string.
85      * @param string $basepage The pagename the plugin is invoked from.
86      * @return array List of pagenames linked to (or false).
87      */
88     function getWikiPageLinks ($argstr, $basepage) {
89         if (isset($this->_links)) 
90             return $this->_links;
91         else {
92             global $request;    
93             $this->run($request->_dbi, $argstr, $request, $basepage);
94             return $this->_links;
95         }
96     }
97
98     function _count_events($dbi, $n = 7, $direction = 1) {
99         //      This is used by the last_n/next_n options to determine the date that
100         //      accounts for the number of N events in the past/future.
101         //      RETURNS: date of N-th event or the last item found
102         $args = &$this->args;                           // gather the args array
103         $timeTMP = time();                              // start with today's date
104         $t = $timeTMP;                                  // init the control date variable to now
105         
106         for ($i=0; $i<=180; $i++) {                     // loop thru 180 days, past or future
107             $date_string = strftime($args['date_format'], $t);
108             $page_for_date = $args['prefix'] . SUBPAGE_SEPARATOR . $date_string;
109             if ($dbi->isWikiPage($page_for_date)) { // if this date has any comments/events
110                 $timeTMP = $t;                      //  capture the date of this event for return
111                 if ($n-- <= 0) break;               //  if we reached the limit, return the date
112             }
113             $t += SECONDS_PER_DAY * $direction;     // advance one day back or forward
114         }
115         
116         // return the date of the N-th or last, most past/future event in the range
117         return $timeTMP;
118     }
119
120     function _date($dbi, $time) {
121         $args = &$this->args;
122         $date_string = strftime($args['date_format'], $time);
123
124         $page_for_date = $args['prefix'] . SUBPAGE_SEPARATOR . $date_string;
125         $t = localtime($time, 1);
126
127         $td = HTML::td(array('align' => 'center'));
128
129         if ($dbi->isWikiPage($page_for_date)) {
130             // Extract the page contents for this date
131             $p = $dbi->getPage($page_for_date);
132             $r = $p->getCurrentRevision();
133             $c = $r->getContent();
134             include_once('lib/BlockParser.php');
135             $content = TransformText(implode("\n", $c), $r->get('markup'));
136             $link = HTML::a(array('class' => 'cal-hide',
137                                   'href'  => WikiURL($page_for_date,
138                                                      array('action' => 'edit')),
139                                   'title' => sprintf(_("Edit %s"), $page_for_date)),
140                             $date_string);
141             $this->_links[] = $page_for_date;
142             $a = array(HTML::dt($link), HTML::dd($content));
143         } else {
144             $a = array();
145         }
146         return $a;
147     }
148
149     function run($dbi, $argstr, &$request, $basepage) {
150         $this->args = $this->getArgs($argstr, $request);
151         $args       = &$this->args;
152         $this->_links = array();
153
154         $now = localtime(time() + 3600 * $request->getPref('timeOffset'), 1);
155         foreach ( array('month' => $now['tm_mon'] + 1,
156                         'year'  => $now['tm_year'] + 1900)
157                   as $param => $dflt ) {
158
159             if (!($args[$param] = intval($args[$param])))
160                 $args[$param]   = $dflt;
161         }
162
163         // set up default range for TODAY only
164         $time = time();
165         $timeBreak = $time;
166
167         // ***************************************************
168         //      SET UP THE START/END DATE CONDITIONS
169         
170         //      last_n_days or last_n events
171         if ($args['last_n_days']) {
172             $timeBreak = time();
173             $time = mktime(23, 59, 54,                      // hh, mm, ss,
174                            $args['month'] + $args['month_offset'], // month (1-12)
175                            $now['tm_mday'] - $args['last_n_days'], // back up so many days
176                            $args['year']);
177         } elseif ($args['last_n']) {
178             $timeBreak = time();
179             $time = $this->_count_events($dbi, $args['last_n'], -1);
180         }
181
182         if ($args['order'] == 'reverse') {      // if reverse order, swap the start/end dates
183             $timeTMP = $time;
184             $time = $timeBreak;
185             $timeBreak = $timeTMP;
186             unset($timeTMP);
187         }
188
189         //      next_n_days or next_n events
190         if ($args['next_n_days']) {
191             if ($args['order'] == 'reverse') {
192                 $time = mktime(23, 59, 54,                         // hh, mm, ss,
193                                $args['month'] + $args['month_offset'], // month (1-12)
194                                $now['tm_mday'] + $args['next_n_days'] ,// starting today + next_n_days
195                                $args['year']);
196             } else {
197                 $timeBreak = mktime(23, 59, 54,                    // hh, mm, ss,
198                                     $args['month'] + $args['month_offset'], // month (1-12)
199                                     $now['tm_mday'] + $args['next_n_days'], // starting at 1st of month
200                                     $args['year']);
201             }
202         } elseif ($args['next_n']) {
203             $timeTMP = $this->_count_events($dbi, $args['next_n'], 1);
204             if ($args['order'] == 'reverse') {
205                 $time = $timeTMP + 5;
206             } else {
207                 $timeBreak = $timeTMP - 5;
208             }
209             unset($timeTMP);
210         }
211
212         // NOTE: I don't know what this does or why it is here, but it was in the original plugin
213         $t = localtime($time, 1);
214         if ($now['tm_year'] == $t['tm_year'] && $now['tm_mon'] == $t['tm_mon'])
215             $this->_today = $now['tm_mday'];
216         else
217             $this->_today = false;
218
219         $cal = HTML::dl();
220
221         $done = false;
222
223         //      all the start/stop range controls are set up now
224         // ***************************************************
225
226         // ***************************************************
227         //      run up or down the date range; this is the real workhorse loop
228         if ($args['order'] == "reverse") {
229             $timeBreak -= SECONDS_PER_DAY;
230         } else {
231             $timeBreak += SECONDS_PER_DAY;
232         }
233         while (!$done) {
234             $success = $cal->pushContent($this->_date($dbi, $time));
235             if ($args['order'] == "reverse") {
236                 $time -= SECONDS_PER_DAY;
237                 if ($time < $timeBreak) {
238                     break;
239                 }
240             } else {
241                 $time += SECONDS_PER_DAY;
242                 if ($time > $timeBreak) {
243                     break;
244                 }
245             }
246         }
247         //      end of Plugin CalendarList display logic
248         // ***************************************************
249
250         return $cal;
251     }
252 };
253
254
255 // $Log: not supported by cvs2svn $
256 // Revision 1.6.2  2005/06/24 12:00:00  mpullen
257 //   Corrected bug in the main WHILE loop to detect proper termination point in time
258 //   {it was stopping one day too soon in either direction}.
259 //
260 // Revision 1.6.1  2005/06/23 12:00:00  mpullen
261 //   Revised to work on all date range combinations (past and future, by days or count of events)
262 //   Externalized five control parameter constants to the config.ini file (new section 8 for PLUGINs)
263 //
264 // Revision 1.6  2005/04/02 03:05:44  uckelman
265 // Removed & from vars passed by reference (not needed, causes PHP to complain).
266 //
267 // Revision 1.5  2004/12/06 19:15:04  rurban
268 // save edit-time links as requested in #946679
269 //
270 // Revision 1.4  2004/12/06 18:32:39  rurban
271 // added order=reverse: feature request from #981109
272 //
273 // Revision 1.3  2004/09/22 13:36:45  rurban
274 // Support ranges, based on a simple patch by JoshWand
275 //   next_n_days, last_n_days, next_n
276 //   last_n not yet
277 //
278 // Revision 1.2  2004/02/17 12:11:36  rurban
279 // added missing 4th basepage arg at plugin->run() to almost all plugins. This caused no harm so far,
280 //      because it was silently dropped on normal usage. However on plugin internal ->run invocations it failed.
281 //      (InterWikiSearch, IncludeSiteMap, ...)
282 //
283 // Revision 1.1  2003/11/18 19:06:03  carstenklapp
284 // New plugin to be used in conjunction with the Calendar plugin.
285 // Upgraded to use SUBPAGE_SEPARATOR for subpages. SF patch tracker
286 // submission 565369.
287 //
288
289
290 // For emacs users
291 // Local Variables:
292 // mode: php
293 // tab-width: 8
294 // c-basic-offset: 4
295 // c-hanging-comment-ender-p: nil
296 // indent-tabs-mode: nil
297 // End:
298 ?>