3 /* Reminder: always indent with 4 spaces (no tabs). */
4 // +---------------------------------------------------------------------------+
5 // | Calendar Plugin 1.1 |
6 // +---------------------------------------------------------------------------+
9 // | This file does two things: 1) it implements the necessary Geeklog Plugin |
10 // | API method and 2) implements all the common code needed by the Calendar |
11 // | plugin's PHP files. |
12 // +---------------------------------------------------------------------------+
13 // | Copyright (C) 2000-2009 by the following authors: |
15 // | Authors: Tony Bibbs - tony AT tonybibbs DOT com |
16 // | Tom Willett - twillett AT users DOT sourceforge DOT net |
17 // | Blaine Lang - langmail AT sympatico DOT ca |
18 // | Dirk Haun - dirk AT haun-online DOT de |
19 // +---------------------------------------------------------------------------+
21 // | This program is free software; you can redistribute it and/or |
22 // | modify it under the terms of the GNU General Public License |
23 // | as published by the Free Software Foundation; either version 2 |
24 // | of the License, or (at your option) any later version. |
26 // | This program is distributed in the hope that it will be useful, |
27 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29 // | GNU General Public License for more details. |
31 // | You should have received a copy of the GNU General Public License |
32 // | along with this program; if not, write to the Free Software Foundation, |
33 // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
35 // +---------------------------------------------------------------------------+
38 * Implementation of the Plugin API for the Calendar plugin
43 if (strpos(strtolower($_SERVER['PHP_SELF']), 'functions.inc') !== false) {
44 die('This file can not be used on its own.');
47 $plugin_path = $_CONF['path'] . 'plugins/calendar/';
48 $langfile = $plugin_path . 'language/' . $_CONF['language'] . '.php';
50 if (file_exists($langfile)) {
51 require_once $langfile;
53 require_once $plugin_path . 'language/english.php';
57 * Check and see if we need to load the plugin configuration
59 if (!isset($_CA_CONF['calendarloginrequired'])) {
60 require_once $_CONF['path_system'] . 'classes/config.class.php';
62 $ca_config = config::get_instance();
63 $_CA_CONF = $ca_config->get_config('calendar');
67 // +---------------------------------------------------------------------------+
68 // | Geeklog Plugin API Implementations |
69 // +---------------------------------------------------------------------------+
72 * Returns the items for this plugin that should appear on the main menu
74 * NOTE: this MUST return the url/value pairs in the following format
75 * $<arrayname>[<label>] = <url>
77 * @return mixed menu entry, or boolean false if disabled / hidden
79 function plugin_getmenuitems_calendar()
81 global $_CONF, $_CA_CONF, $LANG_CAL_1;
83 if (($_CA_CONF['hidecalendarmenu'] == 1) || (COM_isAnonUser() &&
84 ($_CONF['loginrequired'] || $_CA_CONF['calendarloginrequired']))) {
88 $menuitems[$LANG_CAL_1[16]] = $_CONF['site_url'] . '/calendar/index.php';
94 * Returns the upcoming events block
96 * Returns the HTML for any upcoming events in the calendar
98 * @param string $help Help file for block
99 * @param string $title Title to be used in block header
100 * @return string HTML formatted block containing events.
102 function phpblock_calendar( $help='', $title='' )
104 global $_CONF, $_TABLES, $_USER, $_CA_CONF, $LANG_CAL_1, $_DB_dbms;
108 if( !$_USER['noboxes'] && $_CA_CONF['showupcomingevents'] ) {
109 $range = $_CA_CONF['upcomingeventsrange'];
111 $range = 14; // fallback: 14 days
113 $dateonly = $_CONF['dateonly'];
114 if( empty( $dateonly )) {
115 $dateonly = '%d-%b'; // fallback: day - abbrev. month name
118 if( empty( $title )) {
119 $title = DB_getItem( $_TABLES['blocks'], 'title',
120 "name = 'events_block'" );
123 $eventSql = 'SELECT eid,title,url,datestart,dateend,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon '
124 . "FROM {$_TABLES['events']} ";
125 if($_DB_dbms == 'mssql') {
126 $eventSql .= "WHERE dateend >= DATEADD(hh, 24, NOW()) AND (TO_DAYS(datestart) - TO_DAYS(NOW()) < $range) ";
128 $eventSql .= "WHERE dateend >= (NOW() - INTERVAL 24 HOUR) AND (TO_DAYS(datestart) - TO_DAYS(NOW()) < $range) ";
130 $eventSql .= 'ORDER BY datestart,timestart';
132 if(( $_CA_CONF['personalcalendars'] == 1 ) && !empty( $_USER['uid'] )) {
133 $personaleventsql = 'SELECT eid,title,url,datestart,dateend,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon '
134 . "FROM {$_TABLES['personal_events']} ";
135 if($_DB_dbms == 'mssql') {
136 $personaleventsql .= "WHERE uid = {$_USER['uid']} AND dateend >= DATEADD(hh, 24, getUTCDate()) AND (TO_DAYS(datestart) - TO_DAYS(NOW()) < $range) ";
138 $personaleventsql .= "WHERE uid = {$_USER['uid']} AND dateend >= (NOW() - INTERVAL 24 HOUR) AND (TO_DAYS(datestart) - TO_DAYS(NOW()) < $range) ";
140 $personaleventsql .= 'ORDER BY datestart, dateend';
143 $allEvents = DB_query( $eventSql );
144 $numRows = DB_numRows( $allEvents );
145 $totalrows = $numRows;
147 $numDays = 0; // Without limits, I'll force them.
148 $theRow = 1; // Start with today!
149 $oldDate1 = 'no_day'; // Invalid Date!
150 $oldDate2 = 'last_d'; // Invalid Date!
152 if( $_CA_CONF['personalcalendars'] == 1 AND !empty( $_USER['uid'] )) {
159 $skipFirstBreak = false;
161 for( $z = 1; $z <= $iterations; $z++ ) {
163 $allEvents = DB_query( $personaleventsql );
164 $numRows = DB_numRows( $allEvents );
165 $totalrows = $totalrows + $numRows;
167 $numDays = 0; // Without limits, I'll force them.
168 $theRow = 1; // Start with today!
169 $oldDate1 = 'no_day'; // Invalid Date!
170 $oldDate2 = 'last_d'; // Invalid Date!
171 $classname = 'list-new-plugins';
174 $classname = 'list-new-plugins';
177 if( $_CA_CONF['personalcalendars'] == 0 ) {
178 $headline = true; // no headline needed
179 $skipFirstBreak = true;
182 while( $theRow <= $numRows AND $numDays < $range ) {
183 // Retreive the next event, and format the start date.
184 $theEvent = DB_fetchArray( $allEvents );
186 if( SEC_hasAccess( $theEvent['owner_id'], $theEvent['group_id'],
187 $theEvent['perm_owner'], $theEvent['perm_group'],
188 $theEvent['perm_members'], $theEvent['perm_anon'] ) > 0 ) {
194 $retval .= '<p><b>' . $LANG_CAL_1[23] . '</b><br' . XHTML . '>';
197 if( $totalrows > 0 ) {
198 $retval .= '<b>' . $LANG_CAL_1[24] . '</b><br' . XHTML . '>';
204 // Start Date strings...
205 $startDate = $theEvent['datestart'];
206 $theTime1 = strtotime( $startDate );
207 $dayName1 = strftime( '%A', $theTime1 );
208 $abbrDate1 = strftime( $dateonly, $theTime1 );
210 // End Date strings...
211 $endDate = $theEvent['dateend'];
212 $theTime2 = strtotime( $endDate );
213 $dayName2 = strftime( '%A', $theTime2 );
214 $abbrDate2 = strftime( $dateonly, $theTime2 );
216 $todaysEvent = false;
217 if( date( 'Ymd', $theTime1 ) == date( 'Ymd', time())) {
220 $todaysClassName = 'personal-event-today';
222 $todaysClassName = 'site-event-today';
226 // If either of the dates [start/end] change, then display a new header.
227 if( $oldDate1 != $abbrDate1 OR $oldDate2 != $abbrDate2 ) {
228 $oldDate1 = $abbrDate1;
229 $oldDate2 = $abbrDate2;
232 if( $numDays < $range ) {
233 if( !empty( $newevents )) {
234 $retval .= COM_makeList( $newevents, $classname );
236 if( $skipFirstBreak ) {
237 $skipFirstBreak = false;
239 $retval .= '<br' . XHTML . '>';
242 $retval .= '<span class="' . $todaysClassName . '">';
244 $retval .= '<b>' . $dayName1 . '</b> <small>'
245 . $abbrDate1 . '</small>';
247 // If different start and end dates, then display end date:
248 if( $abbrDate1 != $abbrDate2 ) {
249 $retval .= ' - <br' . XHTML . '><b>' . $dayName2 . '</b> <small>' . $abbrDate2 . '</small>';
252 $retval .= '</span>';
255 $newevents = array();
258 // Now display this event record.
259 if( $numDays < $range ) {
260 // Display the url now!
261 $newevent_url = $_CONF['site_url']
262 . '/calendar/event.php?';
265 $newevent_url .= 'mode=personal&';
268 $newevent_url .= 'eid=' . $theEvent['eid'];
271 $attr = array('class' => $todaysClassName);
274 $newevent = COM_createLink(
275 stripslashes( $theEvent['title'] ),
279 $newevents[] = $newevent;
282 if( !empty( $newevents )) {
283 $retval .= COM_makeList( $newevents, $classname );
284 $newevents = array();
291 if( $eventsFound == 0 ) {
292 // There aren't any upcoming events, show a nice message
293 $retval .= $LANG_CAL_1[25];
302 * Checks that the current user has the rights to moderate the
303 * plugin, returns true if this is the case, false otherwise
305 * @return boolean Returns true if moderator
308 function plugin_ismoderator_calendar()
310 return SEC_hasRights('calendar.moderate');
314 * Returns SQL & Language texts to moderation.php
316 function plugin_itemlist_calendar()
318 global $_TABLES, $LANG_CAL_1;
320 if (plugin_ismoderator_calendar()) {
321 $plugin = new Plugin();
322 $plugin->submissionlabel = $LANG_CAL_1[19];
323 $plugin->submissionhelpfile = 'cceventsubmission.html';
324 $plugin->getsubmissionssql = "SELECT eid AS id,title,datestart as day,url "
325 . "FROM {$_TABLES['eventsubmission']} "
326 . "ORDER BY datestart ASC";
327 $plugin->addSubmissionHeading($LANG_CAL_1[20]);
328 $plugin->addSubmissionHeading($LANG_CAL_1[21]);
329 $plugin->addSubmissionHeading($LANG_CAL_1[22]);
336 * returns list of moderation values
338 * The array returned contains (in order): the row 'id' label, main plugin
339 * table, moderation fields (comma seperated), and plugin submission table
341 * @return array Returns array of useful moderation values
344 function plugin_moderationvalues_calendar()
351 "eid,title,description,location,address1,address2,city,state,zipcode,datestart,timestart,dateend,timeend,url,owner_id",
352 $_TABLES['eventsubmission']
358 * Performs plugin exclusive work for items approved by moderation
360 * While moderation.php handles the actual move from linkssubmission
361 * to links tables, within the function we handle all other approval
364 * @param string $id Identifying string
365 * @return string Any wanted HTML output
368 function plugin_moderationapprove_calendar($id)
370 global $_CA_CONF, $_GROUPS, $_TABLES, $_USER;
372 // The eventsubmission table only keeps track of the submitter's uid,
373 // but not of grous and permissions. So set those to sensible defaults.
375 if (isset($_GROUPS['Calendar Admin'])) {
376 $group_id = $_GROUPS['Calendar Admin'];
378 $group_id = SEC_getFeatureGroup('calendar.moderate');
382 SEC_setDefaultPermissions($A, $_CA_CONF['default_permissions']);
384 DB_query("UPDATE {$_TABLES['events']} SET group_id = '$group_id', perm_owner = '{$A['perm_owner']}', perm_group = '{$A['perm_group']}', perm_members = '{$A['perm_members']}', perm_anon = '{$A['perm_anon']}' WHERE eid = '$id'");
390 * Performs plugin exclusive work for items deleted by moderation
392 * While moderation.php handles the actual removal from <plugin>submission
393 * table, within this function we handle all other deletion
396 * @param string $id Identifying string
397 * @return string Any wanted HTML output
400 function plugin_moderationdelete_calendar($id)
404 // these tables should not contain any rows with ml_id = $id
405 // this is done 'just in case'
406 DB_delete ($_TABLES['eventsubmission'], 'eid', $id);
412 * Check calendar submission form for missing fields
413 * and Saves a calendar submission
415 * @param array $A Data for that submission
416 * @return string HTML redirect
419 function plugin_savesubmission_calendar($A)
421 global $_CONF, $_CA_CONF, $_TABLES, $_USER, $LANG12, $LANG_CAL_1;
423 $A['title'] = strip_tags (COM_checkWords ($A['title']));
424 $A['start_year'] = COM_applyFilter ($A['start_year'], true);
425 $A['start_month'] = COM_applyFilter ($A['start_month'], true);
426 $A['start_day'] = COM_applyFilter ($A['start_day'], true);
428 // check for missing textfields
429 if (empty ($A['title']) || empty ($A['start_month']) || empty ($A['start_day']) || empty ($A['start_year'])) {
430 $retval .= COM_siteHeader ('menu', $LANG_CAL_1[27])
431 . COM_startBlock ($LANG12[22], '',
432 COM_getBlockTemplate ('_msg_block', 'header'))
434 . COM_endBlock (COM_getBlockTemplate ('_msg_block', 'footer'))
435 . plugin_submit_calendar ($A['calendar_type'])
440 // check ok, proceed to saving
441 if (isset($A['end_year'])) {
442 $A['end_year'] = COM_applyFilter($A['end_year'], true);
444 if (isset($A['end_month'])) {
445 $A['end_month'] = COM_applyFilter($A['end_month'], true);
447 if (isset($A['end_day'])) {
448 $A['end_day'] = COM_applyFilter($A['end_day'], true);
451 $A['datestart'] = sprintf ('%4d-%02d-%02d',
452 $A['start_year'], $A['start_month'], $A['start_day']);
453 if (empty ($A['end_year']) || empty ($A['end_month']) ||
454 empty ($A['end_day'])) {
455 $A['dateend'] = $A['datestart'];
457 $A['dateend'] = sprintf ('%4d-%02d-%02d',
458 $A['end_year'], $A['end_month'], $A['end_day']);
461 // for the quickadd form, which doesn't have end date/time fields
462 if (!isset ($A['end_hour'])) {
463 $A['end_hour'] = $A['start_hour'];
465 if (!isset ($A['end_minute'])) {
466 $A['end_minute'] = $A['start_minute'];
469 $A['title'] = (isset($A['title']) ? $A['title'] : '');
470 $A['url'] = (isset($A['url']) ? $A['url'] : '');
471 $A['location'] = (isset($A['location']) ? $A['location'] : '');
472 $A['address1'] = (isset($A['address1']) ? $A['address1'] : '');
473 $A['address2'] = (isset($A['address2']) ? $A['address2'] : '');
474 $A['city'] = (isset($A['city']) ? $A['city'] : '');
475 $A['zipcode'] = (isset($A['zipcode']) ? $A['zipcode'] : '');
476 $A['state'] = (isset($A['state']) ? $A['state'] : '');
477 $A['description'] = (isset($A['description']) ? $A['description'] : '');
478 $A['event_type'] = (isset($A['event_type']) ? $A['event_type'] : '');
480 if ($A['url'] == 'http://') {
481 // remove default entry now to avoid false spam reports
485 // pseudo-formatted event description for the spam check
487 if (empty($A['url'])) {
488 $spamcheck .= $A['title'];
490 $spamcheck .= COM_createLink($A['title'], $A['url']);
492 $spamcheck .= '<br' . XHTML . '>' . $A['location'] . '<br' . XHTML . '>'
493 . $A['address1'] . '<br' . XHTML . '>' . $A['address2']
494 . '<br' . XHTML . '>' . $A['city'] . ', ' . $A['zipcode']
495 . '<br' . XHTML . '>' . $A['description'] . '</p>';
496 $result = PLG_checkforSpam($spamcheck, $_CONF['spamx']);
498 COM_updateSpeedlimit('submit');
499 COM_displayMessageAndAbort($result, 'spamx', 403, 'Forbidden');
502 $A['description'] = addslashes (htmlspecialchars (COM_checkWords ($A['description'])));
503 $A['address1'] = addslashes (strip_tags (COM_checkWords ($A['address1'])));
504 $A['address2'] = addslashes (strip_tags (COM_checkWords ($A['address2'])));
505 $A['city'] = addslashes (strip_tags (COM_checkWords ($A['city'])));
506 $A['zipcode'] = addslashes (strip_tags (COM_checkWords ($A['zipcode'])));
507 $A['state'] = addslashes (strip_tags (COM_checkWords ($A['state'])));
508 $A['location'] = addslashes (strip_tags (COM_checkWords ($A['location'])));
509 $A['event_type'] = addslashes (strip_tags (COM_checkWords ($A['event_type'])));
510 $A['title'] = addslashes ($A['title']);
512 $A['url'] = addslashes(COM_sanitizeUrl($A['url']));
514 if (!empty ($A['eid'])) {
515 $A['eid'] = addslashes (COM_applyFilter ($A['eid']));
517 if (empty ($A['eid'])) {
518 $A['eid'] = addslashes (COM_makeSid ());
521 COM_updateSpeedlimit ('submit');
523 if (isset ($A['allday']) && ($A['allday'] == 'on')) {
529 if (isset ($A['hour_mode']) && ($A['hour_mode'] == 24)) {
530 $start_hour = COM_applyFilter ($A['start_hour'], true);
531 if ($start_hour >= 12) {
532 $A['start_ampm'] = 'pm';
533 $A['start_hour'] = $start_hour - 12;
535 $A['start_ampm'] = 'am';
536 $A['start_hour'] = $start_hour;
538 if ($A['start_hour'] == 0) {
539 $A['start_hour'] = 12;
541 $end_hour = COM_applyFilter ($A['end_hour'], true);
542 if ($end_hour >= 12) {
543 $A['end_ampm'] = 'pm';
544 $A['end_hour'] = $end_hour - 12;
546 $A['end_ampm'] = 'am';
547 $A['end_hour'] = $end_hour;
549 if ($A['end_hour'] == 0) {
553 if (!isset ($A['end_ampm'])) {
554 $A['end_ampm'] = $A['start_ampm'];
557 $A['start_hour'] = COM_applyFilter ($A['start_hour'], true);
558 $A['start_minute'] = COM_applyFilter ($A['start_minute'], true);
559 $A['end_hour'] = COM_applyFilter ($A['end_hour'], true);
560 $A['end_minute'] = COM_applyFilter ($A['end_minute'], true);
562 if ($A['start_ampm'] == 'pm' AND $A['start_hour'] <> 12) {
563 $A['start_hour'] = $A['start_hour'] + 12;
565 if ($A['start_ampm'] == 'am' AND $A['start_hour'] == 12) {
566 $A['start_hour'] = '00';
568 if ($A['end_ampm'] == 'pm' AND $A['end_hour'] <> 12) {
569 $A['end_hour'] = $A['end_hour'] + 12;
571 if ($A['end_ampm'] == 'am' AND $A['end_hour'] == 12) {
572 $A['end_hour'] = '00';
574 $A['timestart'] = $A['start_hour'] . ':' . $A['start_minute'] . ':00';
575 $A['timeend'] = $A['end_hour'] . ':' . $A['end_minute'] . ':00';
576 if ($A['calendar_type'] == 'master') { // add to site calendar
578 if (($_CA_CONF['eventsubmission'] == 1) &&
579 !SEC_hasRights('calendar.submit')) {
581 if (COM_isAnonUser()) {
584 $uid = $_USER['uid'];
587 DB_save ($_TABLES['eventsubmission'],
588 'eid,title,event_type,url,datestart,timestart,dateend,timeend,allday,location,address1,address2,city,state,zipcode,description,owner_id',
589 "{$A['eid']},'{$A['title']}','{$A['event_type']}','{$A['url']}','{$A['datestart']}','{$A['timestart']}','{$A['dateend']}','{$A['timeend']}',{$A['allday']},'{$A['location']}','{$A['address1']}','{$A['address2']}','{$A['city']}','{$A['state']}','{$A['zipcode']}','{$A['description']}',{$uid}");
591 if (isset ($_CA_CONF['notification']) &&
592 ($_CA_CONF['notification'] == 1)) {
593 CALENDAR_sendNotification ($_TABLES['eventsubmission'], $A);
596 $retval = COM_refresh($_CONF['site_url']
597 . '/calendar/index.php?msg=4');
599 if (COM_isAnonUser()) {
600 $owner_id = 1; // anonymous user
602 $owner_id = $_USER['uid'];
605 if (SEC_hasRights('calendar.submit')) {
606 $A['group_id'] = SEC_getFeatureGroup('calendar.submit');
608 $A['group_id'] = DB_getItem($_TABLES['groups'], 'grp_id',
609 "grp_name = 'All Users'");
611 SEC_setDefaultPermissions($A, $_CA_CONF['default_permissions']);
613 DB_save ($_TABLES['events'],
614 'eid,title,event_type,url,datestart,timestart,dateend,timeend,allday,location,address1,address2,city,state,zipcode,description,owner_id,group_id,perm_owner,perm_group,perm_members,perm_anon',
615 "{$A['eid']},'{$A['title']}','{$A['event_type']}','{$A['url']}','{$A['datestart']}','{$A['timestart']}','{$A['dateend']}','{$A['timeend']}',{$A['allday']},'{$A['location']}','{$A['address1']}','{$A['address2']}','{$A['city']}','{$A['state']}','{$A['zipcode']}','{$A['description']}',$owner_id,{$A['group_id']},{$A['perm_owner']},{$A['perm_group']},{$A['perm_members']},{$A['perm_anon']}");
617 PLG_itemSaved($A['eid'], 'calendar');
619 if (isset($_CA_CONF['notification']) &&
620 ($_CA_CONF['notification'] == 1)) {
621 CALENDAR_sendNotification($_TABLES['events'], $A);
623 COM_rdfUpToDateCheck('calendar', $A['event_type'], $A['eid']);
625 $retval = COM_refresh($_CONF['site_url']
626 . '/calendar/index.php?msg=17');
629 } else if ($_CA_CONF['personalcalendars'] == 1) { // add to personal calendar
630 if (COM_isAnonUser()) {
631 // anonymous users don't have personal calendars - bail
632 COM_accessLog("Attempt to write to the personal calendar of user '{$A['uid']}'.");
634 $retval = COM_refresh($_CONF['site_url'] . '/calendar/index.php');
636 DB_save ($_TABLES['personal_events'],
637 'uid,eid,title,event_type,url,datestart,timestart,dateend,timeend,allday,location,address1,address2,city,state,zipcode,description',
638 "{$_USER['uid']},'{$A['eid']}','{$A['title']}','{$A['event_type']}','{$A['url']}','{$A['datestart']}','{$A['timestart']}','{$A['dateend']}','{$A['timeend']}',{$A['allday']},'{$A['location']}','{$A['address1']}','{$A['address2']}','{$A['city']}','{$A['state']}','{$A['zipcode']}','{$A['description']}'");
639 $retval = COM_refresh ($_CONF['site_url']
640 . '/calendar/index.php?mode=personal&msg=17');
643 } else { // personal calendars are disabled
644 $retval = COM_refresh ($_CONF['site_url'] . '/calendar/index.php');
650 function plugin_getheadercode_calendar()
656 // use the CSS only if we are on the plugin's pages
657 if (substr_count ($_SERVER['PHP_SELF'], '/calendar/') > 0) {
658 $str = '<link rel="stylesheet" type="text/css" href="'
659 . $_CONF['site_url'] . '/calendar/style.css"' . XHTML . '>';
666 * Shows event submission form or diverts to event editor if admin calls in
669 function plugin_submit_calendar($mode = 'master')
671 global $_CONF, $_USER, $_CA_CONF, $LANG_CAL_1;
673 if (isset($_POST['calendar_type'])) {
674 $mode = $_POST['calendar_type'];
675 } else if (isset($_REQUEST['mode']) && ($_REQUEST['mode'] == 'personal')) {
679 if (($_CA_CONF['personalcalendars'] == 1) && ($mode == 'quickadd')) {
680 // quick add form, just save it.
681 $display = plugin_savesubmission_calendar ($_POST);
683 } else if (SEC_hasRights('calendar.edit') && ($mode != 'personal')) {
684 // admin posts non-personal, go to editor
685 if (isset ($_REQUEST['year'])) {
686 $year = COM_applyFilter ($_REQUEST['year'], true);
688 $year = date ('Y', time ());
690 if (isset ($_REQUEST['month'])) {
691 $month = COM_applyFilter ($_REQUEST['month'], true);
693 $month = date ('m', time ());
695 if (isset ($_REQUEST['day'])) {
696 $day = COM_applyFilter ($_REQUEST['day'], true);
698 $day = date ('d', time ());
700 if (isset ($_REQUEST['hour'])) {
701 $hour = COM_applyFilter ($_REQUEST['hour'], true);
703 $hour = date ('H', time ());
707 $startat = '&datestart='
708 . urlencode (sprintf ('%04d-%02d-%02d', $year,
710 . '&timestart=' . urlencode (sprintf ('%02d:00:00',
714 echo COM_refresh ($_CONF['site_admin_url']
715 . '/plugins/calendar/index.php?mode=edit' . $startat);
718 // otherwise non-admin or admin-personal. do personal form or public submission.
722 $retval .= COM_startBlock ($LANG_CAL_1[26], 'submitevent.html');
723 $eventform = new Template ($_CONF['path'] . 'plugins/calendar/templates/');
724 $eventform->set_file ('eventform', 'submitevent.thtml');
725 if ($mode != 'personal') {
726 $eventform->set_var ('explanation', $LANG_CAL_1[27]);
727 $eventform->set_var ('submit_url', '/submit.php');
729 $eventform->set_var ('explanation', '');
730 $eventform->set_var ('submit_url', '/calendar/index.php?view=savepersonal');
732 if (isset ($_CA_CONF['hour_mode']) && ($_CA_CONF['hour_mode'] == 24)) {
733 $eventform->set_var ('hour_mode', 24);
735 $eventform->set_var ('hour_mode', 12);
737 $eventform->set_var ('site_url', $_CONF['site_url']);
738 $eventform->set_var ('site_admin_url', $_CONF['site_admin_url']);
739 $eventform->set_var ('layout_url', $_CONF['layout_url']);
740 $eventform->set_var ('lang_title', $LANG_CAL_1[28]);
742 $eventform->set_var('lang_eventtype', $LANG_CAL_1[37]);
743 $eventform->set_var('lang_editeventtypes', $LANG_CAL_1[38]);
744 $eventform->set_var('type_options', CALENDAR_eventTypeList ());
746 $eventform->set_var('lang_link', $LANG_CAL_1[43]);
747 $eventform->set_var('max_url_length', 255);
748 $eventform->set_var('lang_startdate', $LANG_CAL_1[21]);
749 $eventform->set_var('lang_starttime', $LANG_CAL_1[30]);
750 if (empty ($month)) {
751 $month = date ('m', time ());
754 $day = date ('d', time ());
757 $year = date ('Y', time ());
759 $eventform->set_var ('month_options', COM_getMonthFormOptions ($month));
760 $eventform->set_var ('day_options', COM_getDayFormOptions ($day));
761 $eventform->set_var ('year_options', COM_getYearFormOptions ($year));
763 if (empty ($hour) || ($hour < 0)) {
764 $cur_hour = date ('H', time ());
768 $cur_hour_24 = $cur_hour % 24;
769 if ($cur_hour >= 12) {
775 $eventform->set_var ('startampm_selection',
776 COM_getAmPmFormSelection ('start_ampm', $ampm));
777 $eventform->set_var ('endampm_selection',
778 COM_getAmPmFormSelection ('end_ampm', $ampm));
780 if ($cur_hour > 12) {
781 $cur_hour = $cur_hour - 12;
782 } else if ($cur_hour == 0) {
786 if (isset ($_CA_CONF['hour_mode']) && ($_CA_CONF['hour_mode'] == 24)) {
787 $eventform->set_var ('hour_options',
788 COM_getHourFormOptions ($cur_hour_24, 24));
790 $eventform->set_var ('hour_options',
791 COM_getHourFormOptions ($cur_hour));
793 $cur_min = intval (date ('i') / 15) * 15;
794 $eventform->set_var ('minute_options',
795 COM_getMinuteFormOptions ($cur_min, 15));
797 $eventform->set_var('lang_enddate', $LANG_CAL_1[18]);
798 $eventform->set_var('lang_endtime', $LANG_CAL_1[29]);
799 $eventform->set_var('lang_alldayevent',$LANG_CAL_1[31]);
800 $eventform->set_var('lang_addressline1',$LANG_CAL_1[32]);
801 $eventform->set_var('lang_addressline2',$LANG_CAL_1[33]);
802 $eventform->set_var('lang_city',$LANG_CAL_1[34]);
803 $eventform->set_var('lang_state',$LANG_CAL_1[35]);
804 $eventform->set_var('state_options', '');
805 $eventform->set_var('lang_zipcode',$LANG_CAL_1[36]);
806 $eventform->set_var('lang_location', $LANG_CAL_1[39]);
807 $eventform->set_var('lang_description', $LANG_CAL_1[5]);
808 $eventform->set_var('lang_htmnotallowed', $LANG_CAL_1[44]);
809 $eventform->set_var('lang_submit', $LANG_CAL_1[45]);
810 $eventform->set_var('mode', $mode);
811 if ($mode == 'personal') {
812 $token = SEC_createToken();
813 $hidden_fields = '<input type="hidden" name="' . CSRF_TOKEN
814 . "\" value=\"{$token}\"" . XHTML . ">";
815 $eventform->set_var('hidden_fields', $hidden_fields);
817 $eventform->set_var('hidden_fields', '');
819 $eventform->set_var('xhtml', XHTML);
820 $eventform->parse('theform', 'eventform');
821 $retval .= $eventform->finish($eventform->get_var('theform'));
822 $retval .= COM_endBlock();
830 * @param string $eid id of event to delete
831 * @param string $type 'submission' when attempting to delete a submission
832 * @param string HTML redirect
834 function CALENDAR_deleteEvent($eid, $type = '')
836 global $_CONF, $_TABLES, $_USER;
838 if (empty($type)) { // delete regular event
839 $result = DB_query("SELECT owner_id,group_id,perm_owner,perm_group,perm_members,perm_anon FROM {$_TABLES['events']} WHERE eid = '$eid'");
840 $A = DB_fetchArray($result);
841 $access = SEC_hasAccess($A['owner_id'], $A['group_id'],
842 $A['perm_owner'], $A['perm_group'], $A['perm_members'],
845 COM_accessLog("User {$_USER['username']} tried to illegally delete event $eid.");
846 return COM_refresh($_CONF['site_admin_url']
847 . '/plugins/calendar/index.php');
850 DB_delete($_TABLES['events'], 'eid', $eid);
851 DB_delete($_TABLES['personal_events'], 'eid', $eid);
853 PLG_itemDeleted($eid, 'calendar');
854 COM_rdfUpToDateCheck('calendar');
856 return COM_refresh($_CONF['site_admin_url'] . '/plugins/calendar/index.php?msg=18');
857 } elseif ($type == 'submission') {
858 if (plugin_ismoderator_calendar()) {
859 DB_delete($_TABLES['eventsubmission'], 'eid', $eid);
861 COM_accessLog("User {$_USER['username']} tried to illegally delete event submission $eid.");
864 COM_accessLog("User {$_USER['username']} tried to illegally delete event $eid of type $type.");
867 return COM_refresh($_CONF['site_admin_url']
868 . '/plugins/calendar/index.php');
871 function CALENDAR_listOld()
873 global $_CONF, $_TABLES, $LANG_ADMIN, $LANG_CAL_ADMIN, $LANG_ACCESS,
874 $LANG01, $_IMAGE_TYPE;
876 if (isset($_REQUEST['usr_time'])) {
877 $usr_time = $_REQUEST['usr_time'];
882 require_once $_CONF['path_system'] . 'lib-admin.php';
886 $header_arr = array( # display 'text' and use table field 'field'
887 array('text' => $LANG_ADMIN['title'], 'field' => 'title', 'sort' => true),
888 array('text' => $LANG_CAL_ADMIN[13], 'field' => 'username', 'sort' => true),
889 array('text' => $LANG_ACCESS['access'], 'field' => 'access', 'sort' => false),
890 array('text' => $LANG_CAL_ADMIN[14], 'field' => 'datestart', 'sort' => true),
891 array('text' => $LANG_CAL_ADMIN[15], 'field' => 'dateend', 'sort' => true)
894 $defsort_arr = array('field' => 'datestart', 'direction' => 'desc');
897 array('url' => $_CONF['site_admin_url'] . '/plugins/calendar/index.php?mode=edit',
898 'text' => $LANG_ADMIN['create_new']),
899 array('url' => $_CONF['site_admin_url'] . '/plugins/calendar/index.php',
900 'text' => $LANG_CAL_ADMIN['32']),
901 array('url' => $_CONF['site_admin_url'],
902 'text' => $LANG_ADMIN['admin_home'])
905 $cal_templates = new Template($_CONF['path'] . 'plugins/calendar/templates/admin');
906 $cal_templates->set_file (array ('form' => 'batchdelete.thtml'));
907 $cal_templates->set_var ('site_admin_url', $_CONF['site_admin_url']);
908 $cal_templates->set_var ('site_url', $_CONF['site_url']);
909 $cal_templates->set_var('layout_url', $_CONF['layout_url']);
910 $cal_templates->set_var('xhtml', XHTML);
911 $cal_templates->set_var ('usr_time', $usr_time);
912 $cal_templates->set_var ('lang_text_start', $LANG_CAL_ADMIN[28]);
913 $cal_templates->set_var ('lang_text_end', $LANG_CAL_ADMIN[29]);
914 $cal_templates->set_var ('lang_updatelist', $LANG_CAL_ADMIN[30]);
915 $cal_templates->set_var ('lang_delete_sel', $LANG_ADMIN['delete_sel']);
916 $cal_templates->set_var ('lang_delconfirm', $LANG_CAL_ADMIN[31]);
917 $cal_templates->parse('form', 'form');
918 $desc = $cal_templates->finish($cal_templates->get_var('form'));
922 'has_extras' => true,
923 'title' => $LANG_CAL_ADMIN[11],
924 'instructions' => $LANG_CAL_ADMIN[27] . $usr_time . "$desc",
925 'form_url' => $_CONF['site_admin_url'] . "/plugins/calendar/index.php?mode=batchdelete"
928 $sql = "SELECT {$_TABLES['events']}.*, {$_TABLES['users']}.username, {$_TABLES['users']}.fullname "
929 ."FROM {$_TABLES['events']} "
930 ."LEFT JOIN {$_TABLES['users']} "
931 ."ON {$_TABLES['events']}.owner_id={$_TABLES['users']}.uid "
934 $filterstr = " AND UNIX_TIMESTAMP() - UNIX_TIMESTAMP(dateend) > " . $usr_time * 2592000 . " ";
939 'query_fields' => array('title', 'datestart', 'dateend'),
940 'default_filter' => $filterstr . COM_getPermSQL('AND')
943 $listoptions = array('chkdelete' => true, 'chkfield' => 'eid');
944 $retval .= ADMIN_createMenu($menu_arr, $LANG_CAL_ADMIN[27] . $usr_time . "$desc", plugin_geticon_calendar());
946 $token = SEC_createToken();
947 $form_arr['bottom'] = "<input type=\"hidden\" name=\"" . CSRF_TOKEN
948 . "\" value=\"{$token}\"" . XHTML . ">";
949 $retval .= ADMIN_list('calendar', 'plugin_getListField_calendar',
950 $header_arr, $text_arr, $query_arr,
951 $defsort_arr, '', '', $listoptions, $form_arr);
958 * This function deletes the events selected in the listOld function
960 * @return string HTML with success or error message
963 function CALENDAR_deleteOld()
965 global $_CONF, $LANG_CAL_ADMIN;
968 $event_list = array();
969 if (isset($_POST['delitem'])) {
970 $event_list = $_POST['delitem'];
973 if (count($event_list) == 0) {
974 $msg = $LANG_CAL_ADMIN[33] . "<br" . XHTML . ">";
977 if (isset($event_list) AND is_array($event_list)) {
978 foreach($event_list as $delitem) {
979 $delitem = COM_applyFilter($delitem);
980 if (!CALENDAR_deleteEvent ($delitem)) {
981 $msg .= "<strong>{$LANG_CAL_ADMIN[34]} $delitem $LANG_CAL_ADMIN[35]}</strong><br" . XHTML . ">\n";
983 $c++; // count the deleted users
988 // Since this function is used for deletion only, its necessary to say that
989 // zero were deleted instead of just leaving this message away.
990 COM_numberFormat($c); // just in case we have more than 999 ...
991 $msg .= "{$LANG_CAL_ADMIN[36]}: $c<br" . XHTML . ">\n";
996 function CALENDAR_listevents()
998 global $_CONF, $_TABLES, $LANG_ADMIN, $LANG_CAL_ADMIN, $LANG_ACCESS,
1001 require_once( $_CONF['path_system'] . 'lib-admin.php' );
1005 $header_arr = array( # display 'text' and use table field 'field'
1006 array('text' => $LANG_ADMIN['edit'], 'field' => 'edit', 'sort' => false),
1007 array('text' => $LANG_ADMIN['copy'], 'field' => 'copy', 'sort' => false),
1008 array('text' => $LANG_ADMIN['title'], 'field' => 'title', 'sort' => true),
1009 array('text' => $LANG_CAL_ADMIN[13], 'field' => 'username', 'sort' => true),
1010 array('text' => $LANG_ACCESS['access'], 'field' => 'access', 'sort' => false),
1011 array('text' => $LANG_CAL_ADMIN[14], 'field' => 'datestart', 'sort' => true),
1012 array('text' => $LANG_CAL_ADMIN[15], 'field' => 'dateend', 'sort' => true)
1015 $defsort_arr = array('field' => 'datestart', 'direction' => 'desc');
1018 array('url' => $_CONF['site_admin_url'] . '/plugins/calendar/index.php?mode=edit',
1019 'text' => $LANG_ADMIN['create_new']),
1020 array('url' => $_CONF['site_admin_url'] . '/plugins/calendar/index.php?mode=batchdelete',
1021 'text' => $LANG_CAL_ADMIN[26]),
1022 array('url' => $_CONF['site_admin_url'],
1023 'text' => $LANG_ADMIN['admin_home'])
1026 $retval .= COM_startBlock($LANG_CAL_ADMIN[11], '',
1027 COM_getBlockTemplate('_admin_block', 'header'));
1028 $retval .= ADMIN_createMenu($menu_arr, $LANG_CAL_ADMIN[12], plugin_geticon_calendar());
1031 'has_extras' => true,
1032 'form_url' => $_CONF['site_admin_url'] . '/plugins/calendar/index.php'
1035 $sql = "SELECT {$_TABLES['events']}.*, {$_TABLES['users']}.username, {$_TABLES['users']}.fullname "
1036 ."FROM {$_TABLES['events']} "
1037 ."LEFT JOIN {$_TABLES['users']} "
1038 ."ON {$_TABLES['events']}.owner_id={$_TABLES['users']}.uid "
1042 'table' => 'events',
1044 'query_fields' => array('title', 'datestart', 'dateend'),
1045 'default_filter' => COM_getPermSQL('AND')
1048 $retval .= ADMIN_list ('calendar', 'plugin_getListField_calendar',
1049 $header_arr, $text_arr, $query_arr,
1052 $retval .= COM_endBlock(COM_getBlockTemplate('_admin_block', 'footer'));
1058 * Send an email notification for a new submission.
1060 * @param string $table Table where the new submission can be found
1061 * @param array $A submission data
1064 function CALENDAR_sendNotification ($table, $A)
1066 global $_CONF, $_TABLES, $LANG01, $LANG08, $LANG09, $LANG_CAL_1, $LANG_CAL_2;
1068 $title = stripslashes ($A['title']);
1069 $description = stripslashes ($A['description']);
1071 $mailbody = "$LANG09[16]: $title\n"
1072 . "$LANG09[17]: " . strftime ($_CONF['date'],
1073 strtotime ($A['datestart'] . ' ' . $A['timestart']));
1075 $mailbody .= ' (' . $LANG_CAL_2[26] . ')';
1078 if (!empty ($A['url']) && ($A['url'] != 'http://')) {
1079 $mailbody .= "$LANG09[33]: <" . $A['url'] . ">\n";
1081 $mailbody .= "\n" . $description . "\n\n";
1082 if ($table == $_TABLES['eventsubmission']) {
1083 $mailbody .= "$LANG01[10] <{$_CONF['site_admin_url']}/moderation.php>\n\n";
1085 $mailbody .= "$LANG_CAL_1[12] <{$_CONF['site_url']}/calendar/event.php?eid={$A['eid']}>\n\n";
1087 $mailsubject = $_CONF['site_name'] . ' ' . $LANG_CAL_2[43];
1089 $mailbody .= "\n------------------------------\n";
1090 $mailbody .= "\n$LANG08[34]\n";
1091 $mailbody .= "\n------------------------------\n";
1093 COM_mail ($_CONF['site_mail'], $mailsubject, $mailbody);
1099 * Counts the items that are submitted
1102 function plugin_submissioncount_calendar()
1108 if( SEC_hasRights( 'calendar.moderate' ))
1110 $num += DB_count( $_TABLES['eventsubmission'] );
1117 * Implements the [event:] autotag.
1120 function plugin_autotags_calendar ($op, $content = '', $autotag = '')
1122 global $_CONF, $_TABLES;
1124 if ($op == 'tagname' ) {
1126 } else if ($op == 'parse') {
1127 $eid = COM_applyFilter($autotag['parm1']);
1128 if (! empty($eid)) {
1129 $url = $_CONF['site_url'] . '/calendar/event.php?eid=' . $eid;
1130 if (empty ($autotag['parm2'])) {
1131 $linktext = stripslashes (DB_getItem ($_TABLES['events'],
1132 'title', "eid = '$eid'"));
1134 $linktext = $autotag['parm2'];
1136 $link = COM_createLink($linktext, $url);
1137 $content = str_replace ($autotag['tagstr'], $link, $content);
1145 * Do we support feeds?
1147 function plugin_getfeednames_calendar()
1153 $feeds[] = array ('id' => 'calendar', 'name' => $LANG_CAL_1[16]);
1160 * Get content for a feed that holds all events.
1162 * @param string $feed feed ID
1163 * @param string $link link to homepage
1164 * @param string $update list of story ids
1165 * @return array content of the feed
1168 function plugin_getfeedcontent_calendar( $feed, &$link, &$update, $feedType, $feedVersion )
1170 global $_CONF, $_TABLES;
1172 $limit = DB_getItem($_TABLES['syndication'], 'limits', "fid = '$feed'");
1175 if( !empty( $limit )) {
1176 if( substr( $limit, -1 ) == 'h' ) {// next xx hours
1178 $hours = substr( $limit, 0, -1 );
1179 $where = " AND (datestart <= DATE_ADD(NOW(), INTERVAL $hours HOUR))";
1182 $limitsql = ' LIMIT ' . $limit;
1186 $limitsql = ' LIMIT 10';
1189 $sql = "SELECT eid,owner_id,title,description FROM {$_TABLES['events']} "
1190 ."WHERE perm_anon > 0 AND dateend >= NOW()$where "
1191 ."ORDER BY datestart,timestart $limitsql";
1192 $result = DB_query($sql);
1196 $nrows = DB_numRows( $result );
1198 for( $i = 1; $i <= $nrows; $i++ )
1200 $row = DB_fetchArray( $result );
1201 $eids[] = $row['eid'];
1203 $eventtitle = stripslashes( $row['title'] );
1204 $eventtext = SYND_truncateSummary( $row['description'], MBYTE_strlen($row['description']));
1205 $eventlink = $_CONF['site_url'] . '/calendar/event.php?eid='
1208 // Need to reparse the date from the event id
1209 $myyear = substr( $row['eid'], 0, 4 );
1210 $mymonth = substr( $row['eid'], 4, 2 );
1211 $myday = substr( $row['eid'], 6, 2 );
1212 $myhour = substr( $row['eid'], 8, 2 );
1213 $mymin = substr( $row['eid'], 10, 2 );
1214 $mysec = substr( $row['eid'], 12, 2 );
1215 $newtime = "{$mymonth}/{$myday}/{$myyear} {$myhour}:{$mymin}:{$mysec}";
1216 $creationtime = strtotime( $newtime );
1217 $extensionTags = array(); // PLG_getFeedElementExtensions('calendar', $row['eid'], $feedType, $feedVersion, $eventtitle, );
1218 $content[] = array( 'title' => $eventtitle,
1219 'summary' => $eventtext,
1220 'link' => $eventlink,
1221 'uid' => $row['owner_id'],
1222 'author' => COM_getDisplayName( $row['owner_id'] ),
1223 'date' => $creationtime,
1224 'format' => 'plaintext',
1225 'extensions' => $extensionTags
1229 $link = $_CONF['site_url'] . '/calendar/index.php';
1230 $update = implode( ',', $eids );
1236 * Checking if calendar feeds are up to date
1238 * @param int $feed id of feed to be checked
1239 * @param string $topic topic (actually: category)
1240 * @param string $update_data data describing current feed contents
1241 * @param string $limit number of entries or number of hours
1242 * @param string $updated_type (optional) type of feed to be updated
1243 * @param string $updated_topic (optional) feed's "topic" to be updated
1244 * @param string $updated_id (optional) id of entry that has changed
1247 function plugin_feedupdatecheck_calendar ($feed, $topic, $update_data, $limit,
1248 $updated_type = '', $updated_topic = '', $updated_id = '')
1250 global $_CONF, $_TABLES, $_SYND_DEBUG;
1253 if( !empty( $limit ))
1255 if( substr( $limit, -1 ) == 'h' ) // next xx hours
1258 $hours = substr( $limit, 0, -1 );
1259 $where = " AND (datestart <= DATE_ADD(NOW(), INTERVAL $hours HOUR))";
1263 $limitsql = ' LIMIT ' . $limit;
1268 $limitsql = ' LIMIT 10';
1271 $result = DB_query( "SELECT eid FROM {$_TABLES['events']} WHERE perm_anon > 0 AND dateend >= NOW()$where ORDER BY datestart,timestart $limitsql" );
1272 $nrows = DB_numRows( $result );
1275 for( $i = 0; $i < $nrows; $i++ )
1277 $A = DB_fetchArray( $result );
1279 if( $A['eid'] == $updated_id )
1281 // no need to look any further - this feed has to be updated
1285 $eids[] = $A['eid'];
1287 $current = implode( ',', $eids );
1290 COM_errorLog ("Update check for events: comparing new list ($current) with old list ($update_info)", 1);
1293 return ( $current != $update_data ) ? false : true;
1298 * Shows the statistics for the Calendar plugin on stats.php.
1299 * If $showsitestats is 1 then we are to only print the overall stats in the
1300 * 'site statistics box' otherwise we show the detailed stats
1302 * @param int showsitestate Flag to let us know which stats to get
1304 function plugin_showstats_calendar ($showsitestats)
1306 global $_CONF, $_TABLES, $LANG_CAL_1;
1311 $result = DB_query("SELECT eid,title,hits FROM {$_TABLES['events']} WHERE (hits > 0)" . COM_getPermSQL ('AND') . " ORDER BY hits DESC LIMIT 10");
1312 $nrows = DB_numRows($result);
1314 $header_arr = array(
1315 array('text' => $LANG_CAL_1[12], 'field' => 'sid', 'header_class' => 'stats-header-title'),
1316 array('text' => $LANG_CAL_1[48], 'field' => 'hits', 'field_class' => 'stats-list-count'),
1318 $data_arr = array();
1319 $text_arr = array('has_menu' => false,
1320 'title' => $LANG_CAL_1[47],
1322 for ($i = 0; $i < $nrows; $i++) {
1323 $A = DB_fetchArray($result);
1324 $A['title'] = stripslashes(str_replace('$','$',$A['title']));
1325 $A['sid'] = COM_createLink($A['title'], $_CONF['site_url']
1326 . "/calendar/event.php?eid={$A['eid']}");
1327 $A['hits'] = COM_NumberFormat ($A['hits']);
1330 $display .= ADMIN_simpleList("", $header_arr, $text_arr, $data_arr);
1332 $display .= COM_startBlock($LANG_CAL_1[47]);
1333 $display .= $LANG_CAL_1[49];
1334 $display .= COM_endBlock();
1341 * New stats plugin API function for proper integration with the site stats
1343 * @return array(item text, item count);
1346 function plugin_statssummary_calendar ()
1348 global $LANG_CAL_1, $_TABLES;
1350 $result = DB_query ("SELECT COUNT(*) AS count FROM {$_TABLES['events']}" . COM_getPermSQL ());
1351 $A = DB_fetchArray ($result);
1352 return array ($LANG_CAL_1[46], COM_NumberFormat ($A['count']));
1357 * This will put an option for the calendar in the command and control block on
1361 function plugin_cclabel_calendar()
1363 global $_CONF, $LANG_CAL_1;
1365 if (SEC_hasRights ('calendar.edit')) {
1366 return array ($LANG_CAL_1[16],
1367 $_CONF['site_admin_url'] . '/plugins/calendar/index.php',
1368 plugin_geticon_calendar ());
1376 * returns the administrative option for this plugin
1379 function plugin_getadminoption_calendar()
1381 global $_CONF, $_TABLES, $LANG_CAL_1;
1383 if (SEC_hasRights ('calendar.edit')) {
1384 $result = DB_query ("SELECT COUNT(*) AS cnt FROM {$_TABLES['events']}" . COM_getPermSQL ());
1385 $A = DB_fetchArray ($result);
1386 $total_events = $A['cnt'];
1388 return array ($LANG_CAL_1[16],
1389 $_CONF['site_admin_url'] . '/plugins/calendar/index.php',
1394 function plugin_getuseroption_calendar()
1396 global $_CONF, $LANG_CAL_1, $_CA_CONF;
1398 if( $_CA_CONF['personalcalendars'] == 1 ) {
1399 $url = $_CONF['site_url'] . '/calendar/index.php?mode=personal';
1400 return array ($LANG_CAL_1[42], $url, '');
1406 * A user is about to be deleted. Update ownership of any events owned
1407 * by that user or delete them.
1409 * @param uid int User id of deleted user
1412 function plugin_user_delete_calendar ($uid)
1414 global $_TABLES, $_CA_CONF;
1416 DB_delete ($_TABLES['personal_events'], 'owner_id', $uid);
1418 if ($_CA_CONF['delete_event'] == 1) {
1419 // delete the events
1420 DB_delete ($_TABLES['events'], 'owner_id', $uid);
1423 // assign ownership to a user from the Root group
1424 $rootgroup = DB_getItem ($_TABLES['groups'], 'grp_id',
1425 "grp_name = 'Root'");
1426 $result = DB_query ("SELECT DISTINCT ug_uid FROM {$_TABLES['group_assignments']} WHERE ug_main_grp_id = $rootgroup ORDER BY ug_uid LIMIT 1");
1427 list($rootuser) = DB_fetchArray ($result);
1428 DB_query ("UPDATE {$_TABLES['events']} SET owner_id = $rootuser WHERE owner_id = $uid");
1433 * Return the current version of code.
1434 * Used in the Plugin Editor to show the registered version and code version
1436 function plugin_chkVersion_calendar()
1440 require_once $_CONF['path'] . 'plugins/calendar/autoinstall.php';
1442 $inst_parms = plugin_autoinstall_calendar('calendar');
1444 return $inst_parms['info']['pi_version'];
1448 * Update the Calendar plugin
1450 * @return int Number of message to display (true = generic success msg)
1453 function plugin_upgrade_calendar()
1455 global $_CONF, $_TABLES, $_DB_dbms;
1457 $installed_version = DB_getItem($_TABLES['plugins'], 'pi_version',
1458 "pi_name = 'calendar'");
1459 $code_version = plugin_chkVersion_calendar();
1460 if ($installed_version == $code_version) {
1465 require_once $_CONF['path'] . 'plugins/calendar/autoinstall.php';
1467 if (! plugin_compatible_with_this_version_calendar('calendar')) {
1471 $inst_parms = plugin_autoinstall_calendar('calendar');
1472 $pi_gl_version = $inst_parms['info']['pi_gl_version'];
1474 require_once $_CONF['path'] . 'plugins/calendar/sql/'
1475 . $_DB_dbms . '_updates.php';
1477 $current_version = $installed_version;
1480 switch ($current_version) {
1482 $current_version = '1.1.0';
1486 if (isset($_UPDATES[$current_version])) {
1487 $_SQL = $_UPDATES[$current_version];
1488 foreach ($_SQL as $sql) {
1493 $current_version = '1.1.1';
1502 DB_query("UPDATE {$_TABLES['plugins']} SET pi_version = '$code_version', pi_gl_version = '$pi_gl_version' WHERE pi_name = 'calendar'");
1508 * Called during site migration - handle changed URLs or paths
1510 * @param array $old_conf contents of the $_CONF array on the old site
1511 * @param boolean true on success, otherwise false
1514 function plugin_migrate_calendar($old_conf)
1519 'events' => 'eid, description, url',
1520 'eventsubmission' => 'eid, description, url',
1521 'personal_events' => 'eid, description, url'
1524 if ($old_conf['site_url'] != $_CONF['site_url']) {
1525 INST_updateSiteUrl($old_conf['site_url'], $_CONF['site_url'], $tables);
1532 * Geeklog informs us that we're about to be enabled or disabled
1534 * @param boolean $enabled true = we're being enabled, false = disabled
1537 function plugin_enablestatechange_calendar ($enable)
1541 $is_enabled = $enable ? 1 : 0;
1543 // toggle calendar feeds
1544 DB_query ("UPDATE {$_TABLES['syndication']} SET is_enabled = $is_enabled WHERE type = 'calendar'");
1546 // toggle upcoming events block
1547 DB_query ("UPDATE {$_TABLES['blocks']} SET is_enabled = $is_enabled WHERE (type = 'phpblock') AND (phpblockfn = 'phpblock_calendar')");
1551 * Automatic uninstall function for plugins
1555 * This code is automatically uninstalling the plugin.
1556 * It passes an array to the core code function that removes
1557 * tables, groups, features and php blocks from the tables.
1558 * Additionally, this code can perform special actions that cannot be
1559 * foreseen by the core code (interactions with other plugins for example)
1562 function plugin_autouninstall_calendar ()
1565 /* give the name of the tables, without $_TABLES[] */
1566 'tables' => array('events','eventsubmission','personal_events'),
1567 /* give the full name of the group, as in the db */
1568 'groups' => array('Calendar Admin'),
1569 /* give the full name of the feature, as in the db */
1570 'features' => array('calendar.edit', 'calendar.moderate', 'calendar.submit'),
1571 /* give the full name of the block, including 'phpblock_', etc */
1572 'php_blocks' => array('phpblock_calendar'),
1573 /* give all vars with their name */
1581 * Get path for the template files.
1583 * @param string $path subdirectory within the base template path
1584 * @return string full path to template directory
1587 function calendar_templatePath ($path = '')
1591 if (empty ($path)) {
1592 $layout_path = $_CONF['path_layout'] . calendar;
1594 $layout_path = $_CONF['path_layout'] . calendar . '/' . $path;
1597 if (is_dir ($layout_path)) {
1598 $retval = $layout_path;
1600 $retval = $_CONF['path'] . 'plugins/calendar/templates';
1601 if (!empty ($path)) {
1602 $retval .= '/' . $path;
1610 * Returns the URL of the plugin's icon
1612 * @return string URL of the icon
1615 function plugin_geticon_calendar ()
1619 return $_CONF['site_url'] . '/calendar/images/calendar.png';
1623 * Geeklog is asking us to provide any items that show up in the type
1624 * drop-down on search.php. Let's users search for events.
1626 * @return array (plugin name/entry title) pair for the dropdown
1629 function plugin_searchtypes_calendar()
1633 $tmp['calendar'] = $LANG_CAL_1[50];
1639 * This searches for events matching the user query and returns an array for the
1640 * header and table rows back to search.php where it will be formated and printed
1642 * @param string $query Keywords user is looking for
1643 * @param date $datestart Start date to get results for
1644 * @param date $dateend End date to get results for
1645 * @param string $topic The topic they were searching in
1646 * @param string $type Type of items they are searching, or 'all' (deprecated)
1647 * @param int $author Get all results by this author
1648 * @param string $keyType search key type: 'all', 'phrase', 'any'
1649 * @param int $page page number of current search (deprecated)
1650 * @param int $perpage number of results per page (deprecated)
1651 * @return object search result object
1654 function plugin_dopluginsearch_calendar($query, $datestart, $dateend, $topic, $type, $author, $keyType, $page, $perpage)
1656 global $_TABLES, $_USER, $LANG_CAL_1;
1658 // Make sure the query is SQL safe
1659 $query = trim(addslashes($query));
1661 if (COM_isAnonUser()) {
1664 $uid = $_USER['uid'];
1667 $sql_e = "SELECT eid AS id, title, description, UNIX_TIMESTAMP(datestart) AS date, owner_id AS uid, hits, ";
1668 $sql_e .= "CONCAT('/calendar/event.php?eid=',eid) AS url ";
1669 $sql_e .= "FROM {$_TABLES['events']} WHERE 1=1 ";
1671 $sql_p = "SELECT eid AS id, title, description, UNIX_TIMESTAMP(datestart) AS date, owner_id AS uid, ";
1672 $sql_p .= "CONCAT('/calendar/event.php?mode=personal&eid=',eid) AS url ";
1673 $sql_p .= "FROM {$_TABLES['personal_events']} WHERE (uid = $uid) ";
1675 $sql = COM_getPermSQL('AND') . ' ';
1677 if (!empty ($author)) {
1678 $sql .= "AND (owner_id = '$author') ";
1681 // Search the public events
1682 $search_e = new SearchCriteria('calendar', array($LANG_CAL_1[16],$LANG_CAL_1[24]));
1684 $columns = array('title' => 'title', 'location', 'description');
1685 $sql .= $search_e->getDateRangeSQL('AND', 'datestart', $datestart, $dateend);
1686 list($sql_tmp,$ftsql_tmp) = $search_e->buildSearchSQL($keyType, $query, $columns, $sql_e . $sql);
1688 $search_e->setSQL($sql_tmp);
1689 $search_e->setFTSQL($ftsql_tmp);
1690 $search_e->setRank(2);
1692 if (COM_isAnonUser()) {
1696 // Search personal events
1697 $search_p = new SearchCriteria('calendar', array($LANG_CAL_1[16],$LANG_CAL_1[23]));
1699 $columns = array('title' => 'title', 'location', 'description');
1700 list($sql_tmp,$ftsql_tmp) = $search_p->buildSearchSQL($keyType, $query, $columns, $sql_p . $sql);
1702 $search_p->setSQL($sql_tmp);
1703 $search_p->setFTSQL($ftsql_tmp);
1704 $search_p->setRank(2);
1706 return array($search_e,$search_p);
1711 * Set template variables
1713 * @param string $templatename name of template, e.g. 'header'
1714 * @param ref $template reference of actual template
1717 * Note: A plugin should use its name as a prefix for the names of its
1718 * template variables, e.g. 'calendar_xxx' and 'lang_calendar_xxx'.
1719 * 'button_calendar' is an exception, as such a variable existed for header.thtml
1720 * in Geeklog 1.4.0 and earlier, where the Calendar was an integral part
1721 * of Geeklog. It is added here for backward-compatibility.
1724 function plugin_templatesetvars_calendar ($templatename, &$template)
1728 if ($templatename == 'header') {
1729 $template->set_var ('button_calendar', $LANG_CAL_1[16]);
1733 function plugin_getListField_calendar($fieldname, $fieldvalue, $A, $icon_arr)
1735 global $_CONF, $LANG_ACCESS, $LANG_ADMIN;
1739 $access = SEC_hasAccess($A['owner_id'],$A['group_id'],$A['perm_owner'],
1740 $A['perm_group'],$A['perm_members'],$A['perm_anon']);
1742 switch($fieldname) {
1744 $retval = "<input type=\"checkbox\" name=\"delitem[{$A['eid']}]\" checked=\"checked\"" . XHTML . ">";
1748 $retval = COM_createLink(
1750 "{$_CONF['site_admin_url']}/plugins/calendar/index.php"
1751 . "?mode=edit&eid={$A['eid']}");
1756 $retval = COM_createLink(
1758 "{$_CONF['site_admin_url']}/plugins/calendar/index.php"
1759 . "?mode=clone&eid={$A['eid']}");
1764 $retval = $LANG_ACCESS['edit'];
1766 $retval = $LANG_ACCESS['readonly'];
1770 $retval = stripslashes ($A['title']);
1771 $retval = COM_createLink( $retval,
1772 "{$_CONF['site_url']}/calendar/event.php?eid={$A['eid']}"
1776 $retval = COM_getDisplayName ($A['owner_id'], $A['username'], $A['fullname']);
1779 $retval = $fieldvalue;
1786 * Creates a dropdown list of all the event types
1788 * @param string $currtype current event type (to preselect in the list)
1789 * @return string <option> list of event types
1792 function CALENDAR_eventTypeList ($currtype = '')
1798 if (!isset($_CA_CONF['event_types']) ||
1799 !is_array($_CA_CONF['event_types'])) {
1800 $event_types = array();
1802 $event_types = $_CA_CONF['event_types'];
1804 asort($event_types);
1806 foreach ($event_types as $type) {
1807 $retval .= '<option value="' . $type . '"';
1808 if ($currtype == $type) {
1809 $retval .= ' selected="selected"';
1811 $retval .= '>' . $type . '</option>';
1818 * Return information for an event
1820 * @param string $eid event ID or '*'
1821 * @param string $what comma-separated list of properties
1822 * @param int $uid user ID or 0 = current user
1823 * @param array $options (reserved for future extensions)
1824 * @return mixed string or array of strings with the information
1827 function plugin_getiteminfo_calendar($eid, $what, $uid = 0, $options = array())
1829 global $_CONF, $_TABLES;
1831 // parse $what to see what we need to pull from the database
1832 $properties = explode(',', $what);
1834 foreach ($properties as $p) {
1836 // no date! we don't keep track of the _item's_ create/modify dates!
1839 $fields[] = 'description';
1845 $fields[] = 'title';
1848 // needed for $eid == '*', but also in case we're only requesting
1849 // the URL (so that $fields isn't emtpy)
1858 $fields = array_unique($fields);
1860 if (count($fields) == 0) {
1866 // prepare SQL request
1871 $where = " WHERE eid = '" . addslashes($eid) . "'";
1875 $permSql = COM_getPermSql($permOp, $uid);
1877 $permSql = COM_getPermSql($permOp);
1879 $sql = "SELECT " . implode(',', $fields)
1880 . " FROM {$_TABLES['events']}" . $where . $permSql;
1885 $result = DB_query($sql);
1886 $numRows = DB_numRows($result);
1889 for ($i = 0; $i < $numRows; $i++) {
1890 $A = DB_fetchArray($result);
1893 foreach ($properties as $p) {
1897 $props[$p] = $A['description'];
1900 $props['id'] = $A['eid'];
1903 $props['title'] = stripslashes($A['title']);
1906 if (empty($A['eid'])) {
1907 $props['url'] = $_CONF['site_url'] . '/calendar/event.php?'
1910 $props['url'] = $_CONF['site_url'] . '/calendar/event.php?'
1911 . 'eid=' . $A['eid'];
1915 // return empty string for unknown properties
1922 foreach ($props as $key => $value) {
1925 $mapped[$key] = $value;
1933 $retval[] = $mapped;
1940 if (($eid != '*') && (count($retval) == 1)) {
1941 $retval = $retval[0];
1948 * Provide URL of a documentation file
1950 * @param string $file documentation file being requested, e.g. 'config'
1951 * @return mixed URL or false when not available
1954 function plugin_getdocumentationurl_calendar($file)
1963 if (isset($docurl)) {
1966 $doclang = COM_getLanguageName();
1967 $docs = 'docs/' . $doclang . '/calendar.html';
1968 if (file_exists($_CONF['path_html'] . $docs)) {
1969 $retval = $_CONF['site_url'] . '/' . $docs;
1971 $retval = $_CONF['site_url'] . '/docs/english/calendar.html';