Calendar - Version 1.2

Version Description

Download this release

Release Info

Developer KieranOShea
Plugin Icon 128x128 Calendar
Version 1.2
Comparing to
See all releases

Version 1.2

Files changed (8) hide show
  1. calendar.php +2342 -0
  2. javascript.js +1463 -0
  3. readme.txt +123 -0
  4. screenshot-1.png +0 -0
  5. screenshot-2.png +0 -0
  6. screenshot-3.png +0 -0
  7. screenshot-4.png +0 -0
  8. screenshot-5.png +0 -0
calendar.php ADDED
@@ -0,0 +1,2342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: Calendar
4
+ Plugin URI: http://www.kjowebservices.co.uk
5
+ Description: This plugin allows you to display a calendar of all your events and appointments as a page on your site.
6
+ Author: Kieran O'Shea
7
+ Author URI: http://www.kjowebservices.co.uk
8
+ Version: 1.2
9
+ */
10
+
11
+ /* Copyright 2008 KJO Web Services (email : sales@kjowebservices.co.uk)
12
+
13
+ This program is free software; you can redistribute it and/or modify
14
+ it under the terms of the GNU General Public License as published by
15
+ the Free Software Foundation; either version 2 of the License, or
16
+ (at your option) any later version.
17
+
18
+ This program is distributed in the hope that it will be useful,
19
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ GNU General Public License for more details.
22
+
23
+ You should have received a copy of the GNU General Public License
24
+ along with this program; if not, write to the Free Software
25
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
+ */
27
+
28
+ // Define the tables used in Calendar
29
+ define('WP_CALENDAR_TABLE', $table_prefix . 'calendar');
30
+ define('WP_CALENDAR_CONFIG_TABLE', $table_prefix . 'calendar_config');
31
+ define('WP_CALENDAR_CATEGORIES_TABLE', $table_prefix . 'calendar_categories');
32
+
33
+ // Create a master category for Calendar and its sub-pages
34
+ add_action('admin_menu', 'calendar_menu');
35
+
36
+ // Enable the ability for the calendar to be loaded from pages
37
+ add_filter('the_content','calendar_insert');
38
+
39
+ // Add the function that puts style information in the header
40
+ add_action('wp_head', 'calendar_wp_head');
41
+
42
+ // Add the function that deals with deleted users
43
+ add_action('delete_user', 'deal_with_deleted_user');
44
+
45
+ // Add the widgets if we are using version 2.5
46
+ add_action('widgets_init', 'widget_init_calendar_today');
47
+ add_action('widgets_init', 'widget_init_calendar_upcoming');
48
+
49
+ // Before we get on with the functions, we need to define the initial style used for Calendar
50
+
51
+ // Function to deal with events posted by a user when that user is deleted
52
+ function deal_with_deleted_user($id)
53
+ {
54
+ global $wpdb;
55
+
56
+ // This wouldn't work unless the database was up to date. Lets check.
57
+ check_calendar();
58
+
59
+ // Do the query
60
+ $wpdb->get_results("UPDATE ".WP_CALENDAR_TABLE." SET event_author=".$wpdb->get_var("SELECT MIN(ID) FROM ".$wpdb->prefix."users",0,0)." WHERE event_author=".$id);
61
+ }
62
+
63
+ // Function to add the calendar style into the header
64
+ function calendar_wp_head()
65
+ {
66
+ global $wpdb;
67
+
68
+ // If the calendar isn't installed or upgraded this won't work
69
+ check_calendar();
70
+
71
+ $styles = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='calendar_style'");
72
+ if (!empty($styles))
73
+ {
74
+ foreach ($styles as $style)
75
+ {
76
+ echo '<style type="text/css">
77
+ <!--
78
+ ';
79
+ echo $style->config_value.'
80
+ ';
81
+ echo '//-->
82
+ </style>
83
+ ';
84
+ }
85
+ }
86
+ }
87
+
88
+ // Function to deal with adding the calendar menus
89
+ function calendar_menu()
90
+ {
91
+ global $wpdb;
92
+
93
+ // We make use of the Calendar tables so we must have installed Calendar
94
+ check_calendar();
95
+
96
+ // Set admin as the only one who can use Calendar for security
97
+ $allowed_group = 'manage_options';
98
+
99
+ // Use the database to *potentially* override the above if allowed
100
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='can_manage_events'");
101
+ if (!empty($configs))
102
+ {
103
+ foreach ($configs as $config)
104
+ {
105
+ $allowed_group = $config->config_value;
106
+ }
107
+ }
108
+
109
+ // Add the admin panel pages for Calendar. Use permissions pulled from above
110
+ if (function_exists('add_menu_page'))
111
+ {
112
+ add_menu_page(__('Calendar'), __('Calendar'), $allowed_group, basename(__FILE__), 'edit_calendar');
113
+ }
114
+ if (function_exists('add_submenu_page'))
115
+ {
116
+ add_submenu_page('calendar.php', __('Manage Calendar'), __('Manage Calendar'), $allowed_group, basename(__FILE__), 'edit_calendar');
117
+ add_action( "admin_print_scripts", 'calendar_add_javascript' );
118
+ // Note only admin can change calendar options
119
+ add_submenu_page('calendar.php', __('Manage Categories'), __('Manage Categories'), 'manage_options', 'manage-categories', 'manage_categories');
120
+ add_submenu_page('calendar.php', __('Calendar Config'), __('Calendar Options'), 'manage_options', 'calendar-config', 'edit_calendar_config');
121
+ }
122
+ }
123
+
124
+ // Function to add the javascript to the admin header
125
+ function calendar_add_javascript()
126
+ {
127
+ //echo '<script type="text/javascript">';
128
+ //echo include('javascript.js');
129
+ //echo '</script>';
130
+ echo '<script type="text/javascript" src="';
131
+ bloginfo('url');
132
+ echo '/wp-content/plugins/calendar/javascript.js"></script>
133
+ <script type="text/javascript">document.write(getCalendarStyles());</script>';
134
+ }
135
+
136
+ // Function to deal with loading the calendar into pages
137
+ function calendar_insert($content)
138
+ {
139
+ if (preg_match('{CALENDAR}',$content))
140
+ {
141
+ $content = str_replace('{CALENDAR}',calendar(),$content);
142
+ }
143
+ return $content;
144
+ }
145
+
146
+ // Function to check what version of Calendar is installed and install if needed
147
+ function check_calendar()
148
+ {
149
+ // Checks to make sure Calendar is installed, if not it adds the default
150
+ // database tables and populates them with test data. If it is, then the
151
+ // version is checked through various means and if it is not up to date
152
+ // then it is upgraded.
153
+
154
+ // Lets see if this is first run and create us a table if it is!
155
+ global $wpdb, $initial_style;
156
+
157
+ // All this style info will go into the database on a new install
158
+ // This looks nice in the Kubrick theme
159
+ $initial_style = " .calnk a:hover {
160
+ background-position:0 0;
161
+ text-decoration:none;
162
+ color:#000000;
163
+ border-bottom:1px dotted #000000;
164
+ }
165
+ .calnk a:visited {
166
+ text-decoration:none;
167
+ color:#000000;
168
+ border-bottom:1px dotted #000000;
169
+ }
170
+ .calnk a {
171
+ text-decoration:none;
172
+ color:#000000;
173
+ border-bottom:1px dotted #000000;
174
+ }
175
+ .calnk a span {
176
+ display:none;
177
+ }
178
+ .calnk a:hover span {
179
+ color:#333333;
180
+ background:#F6F79B;
181
+ display:block;
182
+ position:absolute;
183
+ margin-top:1px;
184
+ padding:5px;
185
+ width:150px;
186
+ z-index:100;
187
+ }
188
+ .calendar-table {
189
+ border:none;
190
+ width:100%;
191
+ }
192
+ .calendar-heading {
193
+ height:25px;
194
+ align:center;
195
+ border:1px solid #D6DED5;
196
+ background-color:#E4EBE3;
197
+ }
198
+ .calendar-next {
199
+ width:25%;
200
+ text-align:center;
201
+ }
202
+ .calendar-prev {
203
+ width:25%;
204
+ text-align:center;
205
+ }
206
+ .calendar-month {
207
+ width:50%;
208
+ text-align:center;
209
+ font-weight:bold;
210
+ }
211
+ .normal-day-heading {
212
+ text-align:center;
213
+ width:25px;
214
+ height:25px;
215
+ font-size:0.8em;
216
+ border:1px solid #DFE6DE;
217
+ background-color:#EBF2EA;
218
+ }
219
+ .weekend-heading {
220
+ text-align:center;
221
+ width:25px;
222
+ height:25px;
223
+ font-size:0.8em;
224
+ border:1px solid #DFE6DE;
225
+ background-color:#EBF2EA;
226
+ color:#FF0000;
227
+ }
228
+ .day-with-date {
229
+ vertical-align:text-top;
230
+ text-align:left;
231
+ width:60px;
232
+ height:60px;
233
+ border:1px solid #DFE6DE;
234
+ }
235
+ .no-events {
236
+
237
+ }
238
+ .day-without-date {
239
+ width:60px;
240
+ height:60px;
241
+ border:1px solid #E9F0E8;
242
+ }
243
+ span.weekend {
244
+ color:#FF0000;
245
+ }
246
+ .current-day {
247
+ vertical-align:text-top;
248
+ text-align:left;
249
+ width:60px;
250
+ height:60px;
251
+ border:1px solid #BFBFBF;
252
+ background-color:#E4EBE3;
253
+ }
254
+ span.event {
255
+ font-size:0.75em;
256
+ }
257
+ .kjo-link {
258
+ font-size:0.75em;
259
+ text-align:center;
260
+ }
261
+ .event-title {
262
+ text-align:center;
263
+ font-weight:bold;
264
+ font-size:1.2em;
265
+ }
266
+ .event-title-break {
267
+ width:96%;
268
+ margin-left:2%;
269
+ margin-right:2%;
270
+ margin-top:5px;
271
+ margin-bottom:5px;
272
+ text-align:center;
273
+ height:1px;
274
+ background-color:#000000;
275
+ }
276
+ .event-content-break {
277
+ width:96%;
278
+ margin-left:2%;
279
+ margin-right:2%;
280
+ margin-top:5px;
281
+ margin-bottom:5px;
282
+ text-align:center;
283
+ height:1px;
284
+ background-color:#000000;
285
+ }
286
+ .calendar-date-switcher {
287
+ height:25px;
288
+ align:center;
289
+ border:1px solid #D6DED5;
290
+ background-color:#E4EBE3;
291
+ }
292
+ .calendar-date-switcher form {
293
+ margin:0;
294
+ padding:0;
295
+ }
296
+ .calendar-date-switcher input {
297
+ border:1px #D6DED5 solid;
298
+ }
299
+ .calendar-date-switcher select {
300
+ border:1px #D6DED5 solid;
301
+ }
302
+ .cat-key {
303
+ width:100%;
304
+ margin-top:10px;
305
+ padding:5px;
306
+ border:1px solid #D6DED5;
307
+ }";
308
+
309
+
310
+ // Assume this is not a new install until we prove otherwise
311
+ $new_install = false;
312
+ $vone_point_one_upgrade = false;
313
+ $vone_point_two_beta_upgrade = false;
314
+
315
+ $wp_calendar_exists = false;
316
+ $wp_calendar_config_exists = false;
317
+ $wp_calendar_config_version_number_exists = false;
318
+
319
+ // Determine the calendar version
320
+ $tables = $wpdb->get_results("show tables;");
321
+ foreach ( $tables as $table )
322
+ {
323
+ foreach ( $table as $value )
324
+ {
325
+ if ( $value == WP_CALENDAR_TABLE )
326
+ {
327
+ $wp_calendar_exists = true;
328
+ }
329
+ if ( $value == WP_CALENDAR_CONFIG_TABLE )
330
+ {
331
+ $wp_calendar_config_exists = true;
332
+
333
+ // We now try and find the calendar version number
334
+ // This will be a lot easier than finding other stuff
335
+ // in the future.
336
+ $version_number = $wpdb->get_var("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='calendar_version'");
337
+ if ($version_number == "1.2")
338
+ {
339
+ $wp_calendar_config_version_number_exists = true;
340
+ }
341
+ }
342
+ }
343
+ }
344
+
345
+ if ($wp_calendar_exists == false && $wp_calendar_config_exists == false)
346
+ {
347
+ $new_install = true;
348
+ }
349
+ else if ($wp_calendar_exists == true && $wp_calendar_config_exists == false)
350
+ {
351
+ $vone_point_one_upgrade = true;
352
+ }
353
+ else if ($wp_calendar_exists == true && $wp_calendar_config_exists == true && $wp_calendar_config_version_number_exists == false)
354
+ {
355
+ $vone_point_two_beta_upgrade = true;
356
+ }
357
+
358
+ // Now we've determined what the current install is or isn't
359
+ // we perform operations according to the findings
360
+ if ( $new_install == true )
361
+ {
362
+ $sql = "CREATE TABLE " . WP_CALENDAR_TABLE . " (
363
+ event_id INT(11) NOT NULL AUTO_INCREMENT ,
364
+ event_begin DATE NOT NULL ,
365
+ event_end DATE NOT NULL ,
366
+ event_title VARCHAR(30) NOT NULL ,
367
+ event_desc TEXT NOT NULL ,
368
+ event_time TIME ,
369
+ event_recur CHAR(1) ,
370
+ event_repeats INT(3) ,
371
+ event_author BIGINT(20) UNSIGNED,
372
+ PRIMARY KEY (event_id)
373
+ )";
374
+ $wpdb->get_results($sql);
375
+ $sql = "CREATE TABLE " . WP_CALENDAR_CONFIG_TABLE . " (
376
+ config_item VARCHAR(30) NOT NULL ,
377
+ config_value TEXT NOT NULL ,
378
+ PRIMARY KEY (config_item)
379
+ )";
380
+ $wpdb->get_results($sql);
381
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='can_manage_events', config_value='edit_posts'";
382
+ $wpdb->get_results($sql);
383
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='calendar_style', config_value='".$initial_style."'";
384
+ $wpdb->get_results($sql);
385
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_author', config_value='false'";
386
+ $wpdb->get_results($sql);
387
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_jump', config_value='false'";
388
+ $wpdb->get_results($sql);
389
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_todays', config_value='true'";
390
+ $wpdb->get_results($sql);
391
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_upcoming', config_value='true'";
392
+ $wpdb->get_results($sql);
393
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_upcoming_days', config_value=7";
394
+ $wpdb->get_results($sql);
395
+
396
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='calendar_version', config_value='1.2'";
397
+ $wpdb->get_results($sql);
398
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='enable_categories', config_value='false'";
399
+ $wpdb->get_results($sql);
400
+ $sql = "ALTER TABLE ".WP_CALENDAR_TABLE." ADD COLUMN event_category BIGINT(20) UNSIGNED";
401
+ $wpdb->get_results($sql);
402
+ $sql = "UPDATE " . WP_CALENDAR_TABLE . " SET event_category=1";
403
+ $wpdb->get_results($sql);
404
+ $sql = "ALTER TABLE ".WP_CALENDAR_TABLE." ADD COLUMN event_link TEXT";
405
+ $wpdb->get_results($sql);
406
+ $sql = "UPDATE " . WP_CALENDAR_TABLE . " SET event_link=''";
407
+ $wpdb->get_results($sql);
408
+ $sql = "CREATE TABLE " . WP_CALENDAR_CATEGORIES_TABLE . " (
409
+ category_id INT(11) NOT NULL AUTO_INCREMENT,
410
+ category_name VARCHAR(30) NOT NULL ,
411
+ category_colour VARCHAR(30) NOT NULL ,
412
+ PRIMARY KEY (category_id)
413
+ )";
414
+ $wpdb->get_results($sql);
415
+ $sql = "INSERT INTO " . WP_CALENDAR_CATEGORIES_TABLE . " SET category_id=0, category_name='General', category_colour='#F6F79B'";
416
+ $wpdb->get_results($sql);
417
+ }
418
+ else if ($vone_point_one_upgrade == true)
419
+ {
420
+ $sql = "ALTER TABLE ".WP_CALENDAR_TABLE." ADD COLUMN event_author BIGINT(20) UNSIGNED";
421
+ $wpdb->get_results($sql);
422
+ $sql = "UPDATE ".WP_CALENDAR_TABLE." SET event_author=".$wpdb->get_var("SELECT MIN(ID) FROM ".$wpdb->prefix."users",0,0);
423
+ $wpdb->get_results($sql);
424
+ $sql = "ALTER TABLE ".WP_CALENDAR_TABLE." MODIFY event_desc TEXT NOT NULL";
425
+ $wpdb->get_results($sql);
426
+ $sql = "CREATE TABLE " . WP_CALENDAR_CONFIG_TABLE . " (
427
+ config_item VARCHAR(30) NOT NULL ,
428
+ config_value TEXT NOT NULL ,
429
+ PRIMARY KEY (config_item)
430
+ )";
431
+ $wpdb->get_results($sql);
432
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='can_manage_events', config_value='edit_posts'";
433
+ $wpdb->get_results($sql);
434
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='calendar_style', config_value='".$initial_style."'";
435
+ $wpdb->get_results($sql);
436
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_author', config_value='false'";
437
+ $wpdb->get_results($sql);
438
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_jump', config_value='false'";
439
+ $wpdb->get_results($sql);
440
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_todays', config_value='true'";
441
+ $wpdb->get_results($sql);
442
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_upcoming', config_value='true'";
443
+ $wpdb->get_results($sql);
444
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='display_upcoming_days', config_value=7";
445
+ $wpdb->get_results($sql);
446
+
447
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='calendar_version', config_value='1.2'";
448
+ $wpdb->get_results($sql);
449
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='enable_categories', config_value='false'";
450
+ $wpdb->get_results($sql);
451
+ $sql = "ALTER TABLE ".WP_CALENDAR_TABLE." ADD COLUMN event_category BIGINT(20) UNSIGNED";
452
+ $wpdb->get_results($sql);
453
+ $sql = "UPDATE " . WP_CALENDAR_TABLE . " SET event_category=1";
454
+ $wpdb->get_results($sql);
455
+ $sql = "ALTER TABLE ".WP_CALENDAR_TABLE." ADD COLUMN event_link TEXT";
456
+ $wpdb->get_results($sql);
457
+ $sql = "UPDATE " . WP_CALENDAR_TABLE . " SET event_link=''";
458
+ $wpdb->get_results($sql);
459
+ $sql = "CREATE TABLE " . WP_CALENDAR_CATEGORIES_TABLE . " (
460
+ category_id INT(11) NOT NULL AUTO_INCREMENT,
461
+ category_name VARCHAR(30) NOT NULL ,
462
+ category_colour VARCHAR(30) NOT NULL ,
463
+ PRIMARY KEY (category_id)
464
+ )";
465
+ $wpdb->get_results($sql);
466
+ $sql = "INSERT INTO " . WP_CALENDAR_CATEGORIES_TABLE . " SET category_id=0, category_name='General', category_colour='#F6F79B'";
467
+ $wpdb->get_results($sql);
468
+ }
469
+ else if ($vone_point_two_beta_upgrade == true)
470
+ {
471
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='calendar_version', config_value='1.2'";
472
+ $wpdb->get_results($sql);
473
+ $sql = "INSERT INTO ".WP_CALENDAR_CONFIG_TABLE." SET config_item='enable_categories', config_value='false'";
474
+ $wpdb->get_results($sql);
475
+ $sql = "ALTER TABLE ".WP_CALENDAR_TABLE." ADD COLUMN event_category BIGINT(20) UNSIGNED";
476
+ $wpdb->get_results($sql);
477
+ $sql = "UPDATE " . WP_CALENDAR_TABLE . " SET event_category=1";
478
+ $wpdb->get_results($sql);
479
+ $sql = "ALTER TABLE ".WP_CALENDAR_TABLE." ADD COLUMN event_link TEXT";
480
+ $wpdb->get_results($sql);
481
+ $sql = "UPDATE " . WP_CALENDAR_TABLE . " SET event_link=''";
482
+ $wpdb->get_results($sql);
483
+ $sql = "CREATE TABLE " . WP_CALENDAR_CATEGORIES_TABLE . " (
484
+ category_id INT(11) NOT NULL AUTO_INCREMENT,
485
+ category_name VARCHAR(30) NOT NULL ,
486
+ category_colour VARCHAR(30) NOT NULL ,
487
+ PRIMARY KEY (category_id)
488
+ )";
489
+ $wpdb->get_results($sql);
490
+ $sql = "INSERT INTO " . WP_CALENDAR_CATEGORIES_TABLE . " SET category_id=1, category_name='General', category_colour='#F6F79B'";
491
+ $wpdb->get_results($sql);
492
+ $sql = "UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value='".$initial_style."' WHERE config_item='calendar_style'";
493
+ $wpdb->get_results($sql);
494
+ }
495
+ }
496
+
497
+ // Used on the manage events admin page to display a list of events
498
+ function wp_events_display_list()
499
+ {
500
+ global $wpdb;
501
+
502
+ $events = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " ORDER BY event_begin DESC");
503
+
504
+ if ( !empty($events) )
505
+ {
506
+ ?>
507
+ <table width="100%" cellpadding="3" cellspacing="3">
508
+ <tr>
509
+ <th scope="col"><?php _e('ID') ?></th>
510
+ <th scope="col"><?php _e('Title') ?></th>
511
+ <th scope="col"><?php _e('Description') ?></th>
512
+ <th scope="col"><?php _e('Start Date') ?></th>
513
+ <th scope="col"><?php _e('End Date') ?></th>
514
+ <th scope="col"><?php _e('Recurs') ?></th>
515
+ <th scope="col"><?php _e('Repeats') ?></th>
516
+ <th scope="col"><?php _e('Author') ?></th>
517
+ <th scope="col"><?php _e('Category') ?></th>
518
+ <th scope="col"><?php _e('Edit') ?></th>
519
+ <th scope="col"><?php _e('Delete') ?></th>
520
+ </tr>
521
+ <?php
522
+ $class = '';
523
+ foreach ( $events as $event )
524
+ {
525
+ $class = ($class == 'alternate') ? '' : 'alternate';
526
+ ?>
527
+ <tr class="<?php echo $class; ?>">
528
+ <th scope="row"><?php echo $event->event_id; ?></th>
529
+ <td><?php echo $event->event_title; ?></td>
530
+ <td><?php echo $event->event_desc; ?></td>
531
+ <td><?php echo $event->event_begin; ?></td>
532
+ <td><?php echo $event->event_end; ?></td>
533
+ <td>
534
+ <?php
535
+ // Interpret the DB values into something human readable
536
+ if ($event->event_recur == 'S') { echo 'Never'; }
537
+ else if ($event->event_recur == 'W') { echo 'Weekly'; }
538
+ else if ($event->event_recur == 'M') { echo 'Monthly'; }
539
+ else if ($event->event_recur == 'Y') { echo 'Yearly'; }
540
+ ?>
541
+ </td>
542
+ <td>
543
+ <?php
544
+ // Interpret the DB values into something human readable
545
+ if ($event->event_recur == 'S') { echo 'N/A'; }
546
+ else if ($event->event_repeats == 0) { echo 'Forever'; }
547
+ else if ($event->event_repeats > 0) { echo $event->event_repeats.' Times'; }
548
+ ?>
549
+ </td>
550
+ <td><?php $e = get_userdata($event->event_author); echo $e->display_name; ?></td>
551
+ <?php
552
+ $sql = "SELECT * FROM " . WP_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".$event->event_category;
553
+ $this_cat = $wpdb->get_row($sql);
554
+ ?>
555
+ <td style="background-color:<?php echo $this_cat->category_colour;?>;"><?php echo $this_cat->category_name; ?></td>
556
+ <?php unset($this_cat); ?>
557
+ <td><a href="<?php echo $_SERVER['REQUEST_URI'] ?>&amp;action=edit&amp;event_id=<?php echo $event->event_id;?>" class='edit'><?php echo __('Edit'); ?></a></td>
558
+ <td><a href="<?php echo $_SERVER['REQUEST_URI'] ?>&amp;action=delete&amp;event_id=<?php echo $event->event_id;?>" class="delete" onclick="return confirm('Are you sure you want to delete this event?')"><?php echo __('Delete'); ?></a></td>
559
+ </tr>
560
+ <?php
561
+ }
562
+ ?>
563
+ </table>
564
+ <?php
565
+ }
566
+ else
567
+ {
568
+ ?>
569
+ <p><?php _e("There are no events in the database!") ?></p>
570
+ <?php
571
+ }
572
+ }
573
+
574
+
575
+ // The event edit form for the manage events admin page
576
+ function wp_events_edit_form($mode='add', $event_id=false)
577
+ {
578
+ global $wpdb;
579
+ $data = false;
580
+
581
+ if ( $event_id !== false )
582
+ {
583
+ if ( intval($event_id) != $event_id )
584
+ {
585
+ echo "<div class=\"error\"><p>Bad Monkey! No banana!</p></div>";
586
+ return;
587
+ }
588
+ else
589
+ {
590
+ $data = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " WHERE event_id='" . mysql_escape_string($event_id) . "' LIMIT 1");
591
+ if ( empty($data) )
592
+ {
593
+ echo "<div class=\"error\"><p>An event with that ID couldn't be found</p></div>";
594
+ return;
595
+ }
596
+ $data = $data[0];
597
+ }
598
+ }
599
+
600
+ ?>
601
+ <div id="pop_up_cal" style="position:absolute;margin-left:150px;visibility:hidden;background-color:white;layer-background-color:white;"></div>
602
+ <form name="quoteform" id="quoteform" class="wrap" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
603
+ <input type="hidden" name="action" value="<?php echo $mode; ?>">
604
+ <input type="hidden" name="event_id" value="<?php echo $event_id; ?>">
605
+
606
+ <div id="item_manager">
607
+ <div style="float: left; width: 98%; clear: both;" class="top">
608
+ <!-- List URL -->
609
+ <fieldset class="small"><legend><?php _e('Event Title'); ?></legend>
610
+ <input type="text" name="event_title" class="input" size="40" maxlength="30"
611
+ value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_title); ?>" />
612
+ </fieldset>
613
+
614
+ <fieldset class="small"><legend><?php _e('Event Description'); ?></legend>
615
+ <textarea name="event_desc" class="input" rows="5" cols="50"><?php if ( !empty($data) ) echo htmlspecialchars($data->event_desc); ?></textarea>
616
+ </fieldset>
617
+
618
+ <fieldset class="small"><legend><?php _e('Event Category'); ?></legend>
619
+ <select name="event_category">
620
+ <?php
621
+ // Grab all the categories and list them
622
+ $sql = "SELECT * FROM " . WP_CALENDAR_CATEGORIES_TABLE;
623
+ $cats = $wpdb->get_results($sql);
624
+ foreach($cats as $cat)
625
+ {
626
+ echo '<option value="'.$cat->category_id.'"';
627
+ if (!empty($data))
628
+ {
629
+ if ($data->event_category == $cat->category_id)
630
+ {
631
+ echo 'selected="selected"';
632
+ }
633
+ }
634
+ echo '>'.$cat->category_name.'</option>
635
+ ';
636
+ }
637
+ ?>
638
+ </select>
639
+ </fieldset>
640
+
641
+ <fieldset class="small"><legend><?php _e('Event Link (Optional)'); ?></legend>
642
+ <input type="text" name="event_link" class="input" size="40" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_link); ?>" />
643
+ </fieldset>
644
+
645
+ <fieldset class="small"><legend><?php _e('Start Date'); ?></legend>
646
+ <script type="text/javascript">
647
+ var cal_begin = new CalendarPopup('pop_up_cal');
648
+ cal_begin.showNavigationDropdowns();
649
+ </script>
650
+ <input type="text" name="event_begin" class="input" size=12
651
+ value="<?php
652
+ if ( !empty($data) )
653
+ {
654
+ echo htmlspecialchars($data->event_begin);
655
+ }
656
+ else
657
+ {
658
+ echo date("Y-m-d");
659
+ }
660
+ ?>" /> <a href="#" onClick="cal_begin.select(document.forms['quoteform'].event_begin,'event_begin_anchor','yyyy-MM-dd'); return false;" name="event_begin_anchor" id="event_begin_anchor">Select Date</a>
661
+ </fieldset>
662
+
663
+ <fieldset class="small"><legend><?php _e('End Date'); ?></legend>
664
+ <script type="text/javascript">
665
+ function check_and_print() {
666
+ var cal_end = new CalendarPopup('pop_up_cal');
667
+ var newDate = new Date();
668
+ newDate.setFullYear(document.forms['quoteform'].event_begin.value.split('-')[0],document.forms['quoteform'].event_begin.value.split('-')[1]-1,document.forms['quoteform'].event_begin.value.split('-')[2]);
669
+ newDate.setDate(newDate.getDate()-1);
670
+ cal_end.addDisabledDates(null, formatDate(newDate, "yyyy-MM-dd"));
671
+ cal_end.showNavigationDropdowns();
672
+ cal_end.select(document.forms['quoteform'].event_end,'event_end_anchor','yyyy-MM-dd');
673
+ }
674
+ </script>
675
+ <input type="text" name="event_end" class="input" size=12
676
+ value="<?php
677
+ if ( !empty($data) )
678
+ {
679
+ echo htmlspecialchars($data->event_end);
680
+ }
681
+ else
682
+ {
683
+ echo date("Y-m-d");
684
+ }
685
+ ?>" /> <a href="#" onClick="check_and_print(); return false;" name="event_end_anchor" id="event_end_anchor">Select Date</a>
686
+ </fieldset>
687
+
688
+ <fieldset class="small"><legend><?php _e('Time (hh:mm)(optional, set blank if not required)'); ?></legend>
689
+ <input type="text" name="event_time" class="input" size=12
690
+ value="<?php
691
+ if ( !empty($data) )
692
+ {
693
+ if ($data->event_time == "00:00:00")
694
+ {
695
+ echo '';
696
+ }
697
+ else
698
+ {
699
+ echo date("H:i",strtotime(htmlspecialchars($data->event_time)));
700
+ }
701
+ }
702
+ else
703
+ {
704
+ echo date("H:i");
705
+ }
706
+ ?>" /> <?php _e('Current time difference from GMT is '); echo get_option('gmt_offset'); _e(' hour(s)'); ?>
707
+ </fieldset>
708
+
709
+ <fieldset class="small"><legend><?php _e('Recurring Events'); ?></legend>
710
+ <?php
711
+ if ($data->event_repeats != NULL)
712
+ {
713
+ $repeats = $data->event_repeats;
714
+ }
715
+ else
716
+ {
717
+ $repeats = 0;
718
+ }
719
+
720
+ if ($data->event_recur == "S")
721
+ {
722
+ $selected_s = 'selected="selected"';
723
+ }
724
+ else if ($data->event_recur == "W")
725
+ {
726
+ $selected_w = 'selected="selected"';
727
+ }
728
+ else if ($data->event_recur == "M")
729
+ {
730
+ $selected_m = 'selected="selected"';
731
+ }
732
+ else if ($data->event_recur == "Y")
733
+ {
734
+ $selected_y = 'selected="selected"';
735
+ }
736
+ ?>
737
+ Repeats for
738
+ <input type="text" name="event_repeats" class="input" size="1" value="<?php echo $repeats; ?>" />
739
+ <select name="event_recur" class="input">
740
+ <option class="input" <?php echo $selected_s; ?> value="S">None</option>
741
+ <option class="input" <?php echo $selected_w; ?> value="W">Weeks</option>
742
+ <option class="input" <?php echo $selected_m; ?> value="M">Months</option>
743
+ <option class="input" <?php echo $selected_y; ?> value="Y">Years</option>
744
+ </select><br />
745
+ Entering 0 means forever. Where the recurrance interval <br />
746
+ is left at none, the event will not reoccur.
747
+ </fieldset>
748
+ <br />
749
+ <input type="submit" name="save" class="button bold" value="Save &raquo;" />
750
+ </div>
751
+ <div style="clear:both; height:1px;">&nbsp;</div>
752
+ </div>
753
+ </form>
754
+ <?php
755
+ }
756
+
757
+ // The actual function called to render the manage events page and
758
+ // to deal with posts
759
+ function edit_calendar()
760
+ {
761
+ global $current_user, $wpdb;
762
+ ?>
763
+ <style type="text/css">
764
+ <!--
765
+ .error {
766
+ background: lightcoral;
767
+ border: 1px solid #e64f69;
768
+ margin: 1em 5% 10px;
769
+ padding: 0 1em 0 1em;
770
+ }
771
+
772
+ .center {
773
+ text-align: center;
774
+ }
775
+ .right { text-align: right;
776
+ }
777
+ .left {
778
+ text-align: left;
779
+ }
780
+ .top {
781
+ vertical-align: top;
782
+ }
783
+ .bold {
784
+ font-weight: bold;
785
+ }
786
+ .private {
787
+ color: #e64f69;
788
+ }
789
+ //-->
790
+ </style>
791
+
792
+ <?php
793
+
794
+ // First some quick cleaning up
795
+ $edit = $create = $save = $delete = false;
796
+
797
+ // Make sure we are collecting the variables we need to select years and months
798
+ $action = !empty($_REQUEST['action']) ? $_REQUEST['action'] : '';
799
+ $event_id = !empty($_REQUEST['event_id']) ? $_REQUEST['event_id'] : '';
800
+
801
+
802
+ // Lets see if this is first run and create us a table if it is!
803
+ check_calendar();
804
+
805
+ // Deal with adding an event to the database
806
+ if ( $action == 'add' )
807
+ {
808
+ $title = !empty($_REQUEST['event_title']) ? $_REQUEST['event_title'] : '';
809
+ $desc = !empty($_REQUEST['event_desc']) ? $_REQUEST['event_desc'] : '';
810
+ $begin = !empty($_REQUEST['event_begin']) ? $_REQUEST['event_begin'] : '';
811
+ $end = !empty($_REQUEST['event_end']) ? $_REQUEST['event_end'] : '';
812
+ $time = !empty($_REQUEST['event_time']) ? $_REQUEST['event_time'] : '';
813
+ $recur = !empty($_REQUEST['event_recur']) ? $_REQUEST['event_recur'] : '';
814
+ $repeats = !empty($_REQUEST['event_repeats']) ? $_REQUEST['event_repeats'] : '';
815
+ $category = !empty($_REQUEST['event_category']) ? $_REQUEST['event_category'] : '';
816
+ $linky = !empty($_REQUEST['event_link']) ? $_REQUEST['event_link'] : '';
817
+
818
+ // Deal with the fools who have left magic quotes turned on
819
+ if ( ini_get('magic_quotes_gpc') )
820
+ {
821
+ $title = stripslashes($title);
822
+ $desc = stripslashes($desc);
823
+ $begin = stripslashes($begin);
824
+ $end = stripslashes($end);
825
+ $time = stripslashes($time);
826
+ $recur = stripslashes($recur);
827
+ $repeats = stripslashes($repeats);
828
+ $category = stripslashes($category);
829
+ $linky = stripslashes($linky);
830
+ }
831
+
832
+ $sql = "INSERT INTO " . WP_CALENDAR_TABLE . " SET event_title='" . mysql_escape_string($title)
833
+ . "', event_desc='" . mysql_escape_string($desc) . "', event_begin='" . mysql_escape_string($begin)
834
+ . "', event_end='" . mysql_escape_string($end) . "', event_time='" . mysql_escape_string($time) . "', event_recur='" . mysql_escape_string($recur) . "', event_repeats='" . mysql_escape_string($repeats) . "', event_author=".$current_user->ID.", event_category=".mysql_escape_string($category).", event_link='".mysql_escape_string($linky)."'";
835
+
836
+ $wpdb->get_results($sql);
837
+
838
+ $sql = "SELECT event_id FROM " . WP_CALENDAR_TABLE . " WHERE event_title='" . mysql_escape_string($title) . "'"
839
+ . " AND event_desc='" . mysql_escape_string($desc) . "' AND event_begin='" . mysql_escape_string($begin) . "' AND event_end='" . mysql_escape_string($end) . "' AND event_recur='" . mysql_escape_string($recur) . "' AND event_repeats='" . mysql_escape_string($repeats) . "' LIMIT 1";
840
+ $result = $wpdb->get_results($sql);
841
+
842
+ if ( empty($result) || empty($result[0]->event_id) )
843
+ {
844
+ ?>
845
+ <div class="error"><p><strong>Error:</strong> For some bizare reason your event was not added. Why not try again?</p></div>
846
+ <?php
847
+ }
848
+ else
849
+ {
850
+ ?>
851
+ <div class="updated"><p>Event added. It will now show in your calendar.</p></div>
852
+ <?php
853
+ }
854
+ }
855
+ // Permit saving of events that have been edited
856
+ elseif ( $action == 'edit_save' )
857
+ {
858
+ $title = !empty($_REQUEST['event_title']) ? $_REQUEST['event_title'] : '';
859
+ $desc = !empty($_REQUEST['event_desc']) ? $_REQUEST['event_desc'] : '';
860
+ $begin = !empty($_REQUEST['event_begin']) ? $_REQUEST['event_begin'] : '';
861
+ $end = !empty($_REQUEST['event_end']) ? $_REQUEST['event_end'] : '';
862
+ $time = !empty($_REQUEST['event_time']) ? $_REQUEST['event_time'] : '';
863
+ $recur = !empty($_REQUEST['event_recur']) ? $_REQUEST['event_recur'] : '';
864
+ $repeats = !empty($_REQUEST['event_repeats']) ? $_REQUEST['event_repeats'] : '';
865
+ $category = !empty($_REQUEST['event_category']) ? $_REQUEST['event_category'] : '';
866
+ $linky = !empty($_REQUEST['event_link']) ? $_REQUEST['event_link'] : '';
867
+
868
+ // Deal with the fools who have left magic quotes turned on
869
+ if ( ini_get('magic_quotes_gpc') )
870
+ {
871
+ $title = stripslashes($title);
872
+ $desc = stripslashes($desc);
873
+ $begin = stripslashes($begin);
874
+ $end = stripslashes($end);
875
+ $time = stripslashes($time);
876
+ $recur = stripslashes($recur);
877
+ $repeats = stripslashes($repeats);
878
+ $category = stripslashes($category);
879
+ $linky = stripslashes($linky);
880
+ }
881
+
882
+ if ( empty($event_id) )
883
+ {
884
+ ?>
885
+ <div class="error"><p><strong>Failure:</strong> You can't update an event if you haven't submitted an event id</p></div>
886
+ <?php
887
+ }
888
+ else
889
+ {
890
+ $sql = "UPDATE " . WP_CALENDAR_TABLE . " SET event_title='" . mysql_escape_string($title)
891
+ . "', event_desc='" . mysql_escape_string($desc) . "', event_begin='" . mysql_escape_string($begin)
892
+ . "', event_end='" . mysql_escape_string($end) . "', event_time='" . mysql_escape_string($time) . "', event_recur='" . mysql_escape_string($recur) . "', event_repeats='" . mysql_escape_string($repeats) . "', event_author=".$current_user->ID . ", event_category=".mysql_escape_string($category).", event_link='".mysql_escape_string($linky)."' WHERE event_id='" . mysql_escape_string($event_id) . "'";
893
+
894
+ $wpdb->get_results($sql);
895
+
896
+ $sql = "SELECT event_id FROM " . WP_CALENDAR_TABLE . " WHERE event_title='" . mysql_escape_string($title) . "'"
897
+ . " AND event_desc='" . mysql_escape_string($desc) . "' AND event_begin='" . mysql_escape_string($begin) . "' AND event_end='" . mysql_escape_string($end) . "' AND event_recur='" . mysql_escape_string($recur) . "' AND event_repeats='" . mysql_escape_string($repeats) . "' LIMIT 1";
898
+ $result = $wpdb->get_results($sql);
899
+
900
+ if ( empty($result) || empty($result[0]->event_id) )
901
+ {
902
+ ?>
903
+ <div class="error"><p><strong>Failure:</strong> For some reason the event didnt update. Why not try again? </p></div>
904
+ <?php
905
+ }
906
+ else
907
+ {
908
+ ?>
909
+ <div class="updated"><p>Event updated successfully</p></div>
910
+ <?php
911
+ }
912
+ }
913
+ }
914
+ // Deal with deleting an event from the database
915
+ elseif ( $action == 'delete' )
916
+ {
917
+ if ( empty($event_id) )
918
+ {
919
+ ?>
920
+ <div class="error"><p><strong>Error:</strong> Good Lord you gave me nothing to delete, nothing I tell you!</p></div>
921
+ <?php
922
+ }
923
+ else
924
+ {
925
+ $sql = "DELETE FROM " . WP_CALENDAR_TABLE . " WHERE event_id='" . mysql_escape_string($event_id) . "'";
926
+ $wpdb->get_results($sql);
927
+
928
+ $sql = "SELECT event_id FROM " . WP_CALENDAR_TABLE . " WHERE event_id='" . mysql_escape_string($event_id) . "'";
929
+ $result = $wpdb->get_results($sql);
930
+
931
+ if ( empty($result) || empty($result[0]->event_id) )
932
+ {
933
+ ?>
934
+ <div class="updated"><p>Event deleted successfully</p></div>
935
+ <?php
936
+ }
937
+ else
938
+ {
939
+ ?>
940
+ <div class="error"><p><strong>Error:</strong> For some bizare reason the event could not be deleted. Why not try again?</p></div>
941
+ <?php
942
+
943
+ }
944
+ }
945
+ }
946
+
947
+ // Now follows a little bit of code that pulls in the main
948
+ // components of this page; the edit form and the list of events
949
+ ?>
950
+
951
+ <div class="wrap">
952
+ <?php
953
+ if ( $action == 'edit' )
954
+ {
955
+ ?>
956
+ <h2><?php _e('Edit Event'); ?></h2>
957
+ <?php
958
+ if ( empty($event_id) )
959
+ {
960
+ echo "<div class=\"error\"><p>Good lord you didn't provide an event id to edit, what were you thinking?</p></div>";
961
+ }
962
+ else
963
+ {
964
+ wp_events_edit_form('edit_save', $event_id);
965
+ }
966
+ }
967
+ else
968
+ {
969
+ ?>
970
+ <h2><?php _e('Add Event'); ?></h2>
971
+ <?php wp_events_edit_form(); ?>
972
+
973
+ <h2><?php _e('Manage Events'); ?></h2>
974
+ <?php
975
+ wp_events_display_list();
976
+ }
977
+ ?>
978
+ </div>
979
+
980
+ <?php
981
+
982
+ }
983
+
984
+ // Display the admin configuration page
985
+ function edit_calendar_config()
986
+ {
987
+ global $wpdb, $initial_style;
988
+
989
+ // We can't use this page unless Calendar is installed/upgraded
990
+ check_calendar();
991
+
992
+ if (isset($_POST['permissions']) && isset($_POST['style']))
993
+ {
994
+ if ($_POST['permissions'] == 'subscriber') { $new_perms = 'read'; }
995
+ else if ($_POST['permissions'] == 'contributor') { $new_perms = 'edit_posts'; }
996
+ else if ($_POST['permissions'] == 'author') { $new_perms = 'publish_posts'; }
997
+ else if ($_POST['permissions'] == 'editor') { $new_perms = 'moderate_comments'; }
998
+ else if ($_POST['permissions'] == 'admin') { $new_perms = 'manage_options'; }
999
+ else { $new_perms = 'manage_options'; }
1000
+
1001
+ $calendar_style = mysql_escape_string($_POST['style']);
1002
+ $display_upcoming_days = mysql_escape_string($_POST['display_upcoming_days']);
1003
+
1004
+ if (mysql_escape_string($_POST['display_author']) == 'on')
1005
+ {
1006
+ $disp_author = 'true';
1007
+ }
1008
+ else
1009
+ {
1010
+ $disp_author = 'false';
1011
+ }
1012
+
1013
+ if (mysql_escape_string($_POST['display_jump']) == 'on')
1014
+ {
1015
+ $disp_jump = 'true';
1016
+ }
1017
+ else
1018
+ {
1019
+ $disp_jump = 'false';
1020
+ }
1021
+
1022
+ if (mysql_escape_string($_POST['display_todays']) == 'on')
1023
+ {
1024
+ $disp_todays = 'true';
1025
+ }
1026
+ else
1027
+ {
1028
+ $disp_todays = 'false';
1029
+ }
1030
+
1031
+ if (mysql_escape_string($_POST['display_upcoming']) == 'on')
1032
+ {
1033
+ $disp_upcoming = 'true';
1034
+ }
1035
+ else
1036
+ {
1037
+ $disp_upcoming = 'false';
1038
+ }
1039
+
1040
+ if (mysql_escape_string($_POST['enable_categories']) == 'on')
1041
+ {
1042
+ $enable_categories = 'true';
1043
+ }
1044
+ else
1045
+ {
1046
+ $enable_categories = 'false';
1047
+ }
1048
+
1049
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$new_perms."' WHERE config_item='can_manage_events'");
1050
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$calendar_style."' WHERE config_item='calendar_style'");
1051
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$disp_author."' WHERE config_item='display_author'");
1052
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$disp_jump."' WHERE config_item='display_jump'");
1053
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$disp_todays."' WHERE config_item='display_todays'");
1054
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$disp_upcoming."' WHERE config_item='display_upcoming'");
1055
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$display_upcoming_days."' WHERE config_item='display_upcoming_days'");
1056
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$enable_categories."' WHERE config_item='enable_categories'");
1057
+
1058
+ // Check to see if we are replacing the original style
1059
+ if (mysql_escape_string($_POST['reset_styles']) == 'on')
1060
+ {
1061
+ $wpdb->get_results("UPDATE " . WP_CALENDAR_CONFIG_TABLE . " SET config_value = '".$initial_style."' WHERE config_item='calendar_style'");
1062
+ }
1063
+
1064
+ echo "<div class=\"updated\"><p><strong>Settings saved.</strong></p></div>";
1065
+ }
1066
+
1067
+ // Pull the values out of the database that we need for the form
1068
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='can_manage_events'");
1069
+ if (!empty($configs))
1070
+ {
1071
+ foreach ($configs as $config)
1072
+ {
1073
+ $allowed_group = $config->config_value;
1074
+ }
1075
+ }
1076
+
1077
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='calendar_style'");
1078
+ if (!empty($configs))
1079
+ {
1080
+ foreach ($configs as $config)
1081
+ {
1082
+ $calendar_style = $config->config_value;
1083
+ }
1084
+ }
1085
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='display_author'");
1086
+ if (!empty($configs))
1087
+ {
1088
+ foreach ($configs as $config)
1089
+ {
1090
+ if ($config->config_value == 'true')
1091
+ {
1092
+ $yes_disp_author = 'selected="selected"';
1093
+ }
1094
+ else
1095
+ {
1096
+ $no_disp_author = 'selected="selected"';
1097
+ }
1098
+ }
1099
+ }
1100
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='display_jump'");
1101
+ if (!empty($configs))
1102
+ {
1103
+ foreach ($configs as $config)
1104
+ {
1105
+ if ($config->config_value == 'true')
1106
+ {
1107
+ $yes_disp_jump = 'selected="selected"';
1108
+ }
1109
+ else
1110
+ {
1111
+ $no_disp_jump = 'selected="selected"';
1112
+ }
1113
+ }
1114
+ }
1115
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='display_todays'");
1116
+ if (!empty($configs))
1117
+ {
1118
+ foreach ($configs as $config)
1119
+ {
1120
+ if ($config->config_value == 'true')
1121
+ {
1122
+ $yes_disp_todays = 'selected="selected"';
1123
+ }
1124
+ else
1125
+ {
1126
+ $no_disp_todays = 'selected="selected"';
1127
+ }
1128
+ }
1129
+ }
1130
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='display_upcoming'");
1131
+ if (!empty($configs))
1132
+ {
1133
+ foreach ($configs as $config)
1134
+ {
1135
+ if ($config->config_value == 'true')
1136
+ {
1137
+ $yes_disp_upcoming = 'selected="selected"';
1138
+ }
1139
+ else
1140
+ {
1141
+ $no_disp_upcoming = 'selected="selected"';
1142
+ }
1143
+ }
1144
+ }
1145
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='display_upcoming_days'");
1146
+ if (!empty($configs))
1147
+ {
1148
+ foreach ($configs as $config)
1149
+ {
1150
+ $upcoming_days = $config->config_value;
1151
+ }
1152
+ }
1153
+ $configs = $wpdb->get_results("SELECT config_value FROM " . WP_CALENDAR_CONFIG_TABLE . " WHERE config_item='enable_categories'");
1154
+ if (!empty($configs))
1155
+ {
1156
+ foreach ($configs as $config)
1157
+ {
1158
+ if ($config->config_value == 'true')
1159
+ {
1160
+ $yes_enable_categories = 'selected="selected"';
1161
+ }
1162
+ else
1163
+ {
1164
+ $no_enable_categories = 'selected="selected"';
1165
+ }
1166
+ }
1167
+ }
1168
+ if ($allowed_group == 'read') { $subscriber_selected='selected="selected"';}
1169
+ else if ($allowed_group == 'edit_posts') { $contributor_selected='selected="selected"';}
1170
+ else if ($allowed_group == 'publish_posts') { $author_selected='selected="selected"';}
1171
+ else if ($allowed_group == 'moderate_comments') { $editor_selected='selected="selected"';}
1172
+ else if ($allowed_group == 'manage_options') { $admin_selected='selected="selected"';}
1173
+
1174
+ // Now we render the form
1175
+ ?>
1176
+ <style type="text/css">
1177
+ <!--
1178
+ .error {
1179
+ background: lightcoral;
1180
+ border: 1px solid #e64f69;
1181
+ margin: 1em 5% 10px;
1182
+ padding: 0 1em 0 1em;
1183
+ }
1184
+
1185
+ .center {
1186
+ text-align: center;
1187
+ }
1188
+ .right {
1189
+ text-align: right;
1190
+ }
1191
+ .left {
1192
+ text-align: left;
1193
+ }
1194
+ .top {
1195
+ vertical-align: top;
1196
+ }
1197
+ .bold {
1198
+ font-weight: bold;
1199
+ }
1200
+ .private {
1201
+ color: #e64f69;
1202
+ }
1203
+ //-->
1204
+ </style>
1205
+
1206
+ <div class="wrap">
1207
+ <h2><?php _e('Calendar Options'); ?></h2>
1208
+ <form name="quoteform" id="quoteform" class="wrap" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
1209
+ <div id="item_manager">
1210
+ <div style="float: left; width: 98%; clear: both;" class="top">
1211
+ <fieldset class="small"><legend><?php _e('Choose the lowest user group that may manage events'); ?></legend>
1212
+ <select name="permissions">
1213
+ <option value="subscriber"<?php echo $subscriber_seletced ?>><?php _e('Subscriber')?></option>
1214
+ <option value="contributor" <?php echo $contributor_selected ?>><?php _e('Contributor')?></option>
1215
+ <option value="author" <?php echo $author_selected ?>><?php _e('Author')?></option>
1216
+ <option value="editor" <?php echo $editor_selected ?>><?php _e('Editor')?></option>
1217
+ <option value="admin" <?php echo $admin_selected ?>><?php _e('Administrator')?></option>
1218
+ </select>
1219
+ </fieldset>
1220
+ <fieldset class="small"><legend><?php _e('Do you want to display the author name on events?'); ?></legend>
1221
+ <select name="display_author">
1222
+ <option value="on" <?php echo $yes_disp_author ?>><?php _e('Yes') ?></option>
1223
+ <option value="off" <?php echo $no_disp_author ?>><?php _e('No') ?></option>
1224
+ </select>
1225
+ </fieldset>
1226
+ <fieldset class="small"><legend><?php _e('Display a jumpbox for changing month and year quickly?'); ?></legend>
1227
+ <select name="display_jump">
1228
+ <option value="on" <?php echo $yes_disp_jump ?>><?php _e('Yes') ?></option>
1229
+ <option value="off" <?php echo $no_disp_jump ?>><?php _e('No') ?></option>
1230
+ </select>
1231
+ </fieldset>
1232
+ <fieldset class="small"><legend><?php _e('Display todays events?'); ?></legend>
1233
+ <select name="display_todays">
1234
+ <option value="on" <?php echo $yes_disp_todays ?>><?php _e('Yes') ?></option>
1235
+ <option value="off" <?php echo $no_disp_todays ?>><?php _e('No') ?></option>
1236
+ </select>
1237
+ </fieldset>
1238
+ <fieldset class="small"><legend><?php _e('Display upcoming events? If yes, state for how many days into the future'); ?></legend>
1239
+ <select name="display_upcoming">
1240
+ <option value="on" <?php echo $yes_disp_upcoming ?>><?php _e('Yes') ?></option>
1241
+ <option value="off" <?php echo $no_disp_upcoming ?>><?php _e('No') ?></option>
1242
+ </select>
1243
+ for <input type="text" name="display_upcoming_days" value="<?php echo $upcoming_days ?>" size="1" maxlength="2" /> days into the future
1244
+ </fieldset>
1245
+
1246
+ <fieldset class="small"><legend><?php _e('Enable event categories?'); ?></legend>
1247
+ <select name="enable_categories">
1248
+ <option value="on" <?php echo $yes_enable_categories ?>><?php _e('Yes') ?></option>
1249
+ <option value="off" <?php echo $no_enable_categories ?>><?php _e('No') ?></option>
1250
+ </select>
1251
+ </fieldset>
1252
+
1253
+ <fieldset class="small"><legend><?php _e('Configure the stylesheet for Calendar'); ?></legend>
1254
+ <textarea name="style" rows="10" cols="60" tabindex="2"><?php echo $calendar_style; ?></textarea>
1255
+ </fieldset>
1256
+ <fieldset class="small"><legend><?php _e('Reset Styles'); ?></legend>
1257
+ <input type="checkbox" name="reset_styles" /> <?php _e('Tick this box if you wish to reset the Calendar style to default'); ?>
1258
+ </fieldset>
1259
+ <br />
1260
+ <input type="submit" name="save" class="button bold" value="Save &raquo;" />
1261
+ </div>
1262
+ </div>
1263
+ </form>
1264
+ </div>
1265
+ <?php
1266
+
1267
+
1268
+ }
1269
+
1270
+ // Function to handle the management of categories
1271
+ function manage_categories()
1272
+ {
1273
+ global $wpdb;
1274
+
1275
+ // Calendar must be installed and upgraded before this will work
1276
+ check_calendar();
1277
+
1278
+ ?>
1279
+ <style type="text/css">
1280
+ <!--
1281
+ .error {
1282
+ background: lightcoral;
1283
+ border: 1px solid #e64f69;
1284
+ margin: 1em 5% 10px;
1285
+ padding: 0 1em 0 1em;
1286
+ }
1287
+
1288
+ .center {
1289
+ text-align: center;
1290
+ }
1291
+ .right {
1292
+ text-align: right;
1293
+ }
1294
+ .left {
1295
+ text-align: left;
1296
+ }
1297
+ .top {
1298
+ vertical-align: top;
1299
+ }
1300
+ .bold {
1301
+ font-weight: bold;
1302
+ }
1303
+ .private {
1304
+ color: #e64f69;
1305
+ }
1306
+ //-->
1307
+ </style>
1308
+ <?php
1309
+ // We do some checking to see what we're doing
1310
+ if (isset($_POST['mode']) && $_POST['mode'] == 'add')
1311
+ {
1312
+ $sql = "INSERT INTO " . WP_CALENDAR_CATEGORIES_TABLE . " SET category_name='".mysql_escape_string($_POST['category_name'])."', category_colour='".mysql_escape_string($_POST['category_colour'])."'";
1313
+ $wpdb->get_results($sql);
1314
+ echo "<div class=\"updated\"><p><strong>Category added successfully</strong></p></div>";
1315
+ }
1316
+ else if (isset($_GET['mode']) && isset($_GET['category_id']) && $_GET['mode'] == 'delete')
1317
+ {
1318
+ $sql = "DELETE FROM " . WP_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".mysql_escape_string($_GET['category_id']);
1319
+ $wpdb->get_results($sql);
1320
+ $sql = "UPDATE " . WP_CALENDAR_TABLE . " SET event_category=1 WHERE event_category=".mysql_escape_string($_GET['category_id']);
1321
+ $wpdb->get_results($sql);
1322
+ echo "<div class=\"updated\"><p><strong>Category deleted successfully</strong></p></div>";
1323
+ }
1324
+ else if (isset($_GET['mode']) && isset($_GET['category_id']) && $_GET['mode'] == 'edit' && !isset($_POST['mode']))
1325
+ {
1326
+ $sql = "SELECT * FROM " . WP_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".mysql_escape_string($_GET['category_id']);
1327
+ $cur_cat = $wpdb->get_row($sql);
1328
+ ?>
1329
+ <div class="wrap">
1330
+ <h2><?php _e('Edit Category'); ?></h2>
1331
+ <form name="catform" id="catform" class="wrap" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
1332
+ <input type="hidden" name="mode" value="edit" />
1333
+ <input type="hidden" name="category_id" value="<?php echo $cur_cat->category_id ?>" />
1334
+ <div id="item_manager">
1335
+ <div style="float: left; width: 98%; clear: both;" class="top">
1336
+ <fieldset class="small"><legend><?php _e('Category Name:'); ?></legend>
1337
+ <input type="text" name="category_name" class="input" size="30" maxlength="30" value="<?php echo $cur_cat->category_name ?>" />
1338
+ </fieldset>
1339
+ <fieldset class="small"><legend><?php _e('Category Colour (Hex format):'); ?></legend>
1340
+ <input type="text" name="category_colour" class="input" size="10" maxlength="7" value="<?php echo $cur_cat->category_colour ?>" />
1341
+ </fieldset>
1342
+ <br />
1343
+ <input type="submit" name="save" class="button bold" value="Save &raquo;" />
1344
+ </div>
1345
+ </div>
1346
+ </form>
1347
+ </div>
1348
+ <?php
1349
+ }
1350
+ else if (isset($_POST['mode']) && isset($_POST['category_id']) && isset($_POST['category_name']) && isset($_POST['category_colour']) && $_POST['mode'] == 'edit')
1351
+ {
1352
+ $sql = "UPDATE " . WP_CALENDAR_CATEGORIES_TABLE . " SET category_name='".mysql_escape_string($_POST['category_name'])."', category_colour='".mysql_escape_string($_POST['category_colour'])."' WHERE category_id=".mysql_escape_string($_POST['category_id']);
1353
+ $wpdb->get_results($sql);
1354
+ echo "<div class=\"updated\"><p><strong>Category edited successfully</strong></p></div>";
1355
+ }
1356
+
1357
+ if ($_GET['mode'] != 'edit' || $_POST['mode'] == 'edit')
1358
+ {
1359
+ ?>
1360
+
1361
+ <div class="wrap">
1362
+ <h2><?php _e('Add Category'); ?></h2>
1363
+ <form name="catform" id="catform" class="wrap" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
1364
+ <input type="hidden" name="mode" value="add" />
1365
+ <input type="hidden" name="category_id" value="">
1366
+ <div id="item_manager">
1367
+ <div style="float: left; width: 98%; clear: both;" class="top">
1368
+ <fieldset class="small"><legend><?php _e('Category Name:'); ?></legend>
1369
+ <input type="text" name="category_name" class="input" size="30" maxlength="30" value="" />
1370
+ </fieldset>
1371
+ <fieldset class="small"><legend><?php _e('Category Colour (Hex format):'); ?></legend>
1372
+ <input type="text" name="category_colour" class="input" size="10" maxlength="7" value="" />
1373
+ </fieldset>
1374
+ <br />
1375
+ <input type="submit" name="save" class="button bold" value="Save &raquo;" />
1376
+ </div>
1377
+ </div>
1378
+ </form>
1379
+ <h2><?php _e('Manage Categories'); ?></h2>
1380
+ <?php
1381
+
1382
+ // We pull the categories from the database
1383
+ $categories = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_CATEGORIES_TABLE . " ORDER BY category_id ASC");
1384
+
1385
+ if ( !empty($categories) )
1386
+ {
1387
+ ?>
1388
+ <table width="50%" cellpadding="3" cellspacing="3">
1389
+ <tr>
1390
+ <th scope="col"><?php _e('ID') ?></th>
1391
+ <th scope="col"><?php _e('Category Name') ?></th>
1392
+ <th scope="col"><?php _e('Category Colour') ?></th>
1393
+ <th scope="col"><?php _e('Edit') ?></th>
1394
+ <th scope="col"><?php _e('Delete') ?></th>
1395
+ </tr>
1396
+ <?php
1397
+ $class = '';
1398
+ foreach ( $categories as $category )
1399
+ {
1400
+ $class = ($class == 'alternate') ? '' : 'alternate';
1401
+ ?>
1402
+ <tr class="<?php echo $class; ?>">
1403
+ <th scope="row"><?php echo $category->category_id; ?></th>
1404
+ <td><?php echo $category->category_name; ?></td>
1405
+ <td style="background-color:<?php echo $category->category_colour; ?>;">&nbsp;</td>
1406
+ <td><a href="<?php echo $_SERVER['REQUEST_URI'] ?>&amp;mode=edit&amp;category_id=<?php echo $category->category_id;?>" class='edit'><?php echo __('Edit'); ?></a></td>
1407
+ <?php
1408
+ if ($category->category_id == 1)
1409
+ {
1410
+ ?>
1411
+ <td>N/A</td>
1412
+ <?php
1413
+ }
1414
+ else
1415
+ {
1416
+ ?>
1417
+ <td><a href="<?php echo $_SERVER['REQUEST_URI'] ?>&amp;mode=delete&amp;category_id=<?php echo $category->category_id;?>" class="delete" onclick="return confirm('Are you sure you want to delete this category?')"><?php echo __('Delete'); ?></a></td>
1418
+ <?php
1419
+ }
1420
+ ?>
1421
+ </tr>
1422
+ <?php
1423
+ }
1424
+ ?>
1425
+ </table>
1426
+ <?php
1427
+ }
1428
+ else
1429
+ {
1430
+ ?>
1431
+ <p><?php _e("There are no categories in the database - something has gone wrong!") ?></p>
1432
+ <?php
1433
+ }
1434
+
1435
+ ?>
1436
+ </div>
1437
+
1438
+ <?php
1439
+ }
1440
+ }
1441
+
1442
+ // Function to return a prefix which will allow the correct
1443
+ // placement of arguments into the query string.
1444
+ function permalink_prefix()
1445
+ {
1446
+ // Get the permalink structure from WordPress
1447
+ $p_link = get_permalink();
1448
+
1449
+ // Work out what the real URL we are viewing is
1450
+ $s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
1451
+ $protocol = substr(strtolower($_SERVER["SERVER_PROTOCOL"]), 0, strpos(strtolower($_SERVER["SERVER_PROTOCOL"]), "/")).$s;
1452
+ $port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
1453
+ $real_link = $protocol.'://'.$_SERVER['SERVER_NAME'].$port.$_SERVER['REQUEST_URI'];
1454
+
1455
+ // Now use all of that to get the correctly craft the Calendar link prefix
1456
+ if (strstr($p_link, '?') && $p_link == $real_link)
1457
+ {
1458
+ $link_part = $p_link.'&';
1459
+ }
1460
+ else if ($p_link == $real_link)
1461
+ {
1462
+ $link_part = $p_link.'?';
1463
+ }
1464
+ else if (strstr($real_link, '?'))
1465
+ {
1466
+ if (isset($_GET['month']) && isset($_GET['yr']))
1467
+ {
1468
+ $new_tail = split("&", $real_link);
1469
+ foreach ($new_tail as $item)
1470
+ {
1471
+ if (!strstr($item, 'month') && !strstr($item, 'yr'))
1472
+ {
1473
+ $link_part .= $item.'&';
1474
+ }
1475
+ }
1476
+ if (!strstr($link_part, '?'))
1477
+ {
1478
+ $new_tail = split("month", $link_part);
1479
+ $link_part = $new_tail[0].'?'.$new_tail[1];
1480
+ }
1481
+ }
1482
+ else
1483
+ {
1484
+ $link_part = $real_link.'&';
1485
+ }
1486
+ }
1487
+ else
1488
+ {
1489
+ $link_part = $real_link.'?';
1490
+ }
1491
+
1492
+ return $link_part;
1493
+ }
1494
+
1495
+ // Configure the "Next" link in the calendar
1496
+ function next_link($cur_year,$cur_month)
1497
+ {
1498
+ $mod_rewrite_months = array(1=>'jan','feb','mar','apr','may','jun','jul','aug','sept','oct','nov','dec');
1499
+ $next_year = $cur_year + 1;
1500
+
1501
+ if ($cur_month == 12)
1502
+ {
1503
+ return '<a href="' . permalink_prefix() . 'month=jan&yr=' . $next_year . '">Next &raquo;</a>';
1504
+ }
1505
+ else
1506
+ {
1507
+ $next_month = $cur_month + 1;
1508
+ $month = $mod_rewrite_months[$next_month];
1509
+ return '<a href="' . permalink_prefix() . 'month='.$month.'&yr=' . $cur_year . '">Next &raquo;</a>';
1510
+ }
1511
+ }
1512
+
1513
+ // Configure the "Previous" link in the calendar
1514
+ function prev_link($cur_year,$cur_month)
1515
+ {
1516
+ $mod_rewrite_months = array(1=>'jan','feb','mar','apr','may','jun','jul','aug','sept','oct','nov','dec');
1517
+ $last_year = $cur_year - 1;
1518
+
1519
+ if ($cur_month == 1)
1520
+ {
1521
+ return '<a href="' . permalink_prefix() . 'month=dec&yr='. $last_year .'">&laquo; Prev</a>';
1522
+ }
1523
+ else
1524
+ {
1525
+ $next_month = $cur_month - 1;
1526
+ $month = $mod_rewrite_months[$next_month];
1527
+ return '<a href="' . permalink_prefix() . 'month='.$month.'&yr=' . $cur_year . '">&laquo; Prev</a>';
1528
+ }
1529
+ }
1530
+
1531
+ // Print upcoming events
1532
+ function upcoming_events()
1533
+ {
1534
+ global $wpdb;
1535
+
1536
+ // This function cannot be called unless calendar is up to date
1537
+ check_calendar();
1538
+
1539
+ // Find out if we should be displaying upcoming events
1540
+ $display = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='display_upcoming'",0,0);
1541
+
1542
+ if ($display == 'true')
1543
+ {
1544
+ // Get number of days we should go into the future
1545
+ $future_days = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='display_upcoming_days'",0,0);
1546
+ $day_count = 1;
1547
+
1548
+ while ($day_count < $future_days+1)
1549
+ {
1550
+ list($y,$m,$d) = split("-",date("Y-m-d",mktime($day_count*24,0,0,date("m"),date("d"),date("Y"))));
1551
+ $events = grab_events($y,$m,$d);
1552
+ usort($events, "time_cmp");
1553
+ if (count($events) != 0) {
1554
+ $output .= '<li>'.date(get_option('date_format'),mktime($day_count*24,0,0,date("m"),date("d"),date("Y"))).'<ul>';
1555
+ }
1556
+ foreach($events as $event)
1557
+ {
1558
+ if ($event->event_time == '00:00:00') {
1559
+ $time_string = ' all day';
1560
+ }
1561
+ else {
1562
+ $time_string = ' at '.date(get_option('time_format'), strtotime($event->event_time));
1563
+ }
1564
+ $output .= '<li>'.draw_widget_event($event).$time_string.'</li>';
1565
+ }
1566
+ if (count($events) != 0) {
1567
+ $output .= '</ul></li>';
1568
+ }
1569
+ $day_count = $day_count+1;
1570
+ }
1571
+
1572
+ if ($output != '')
1573
+ {
1574
+ $visual = '<li class="upcoming-events"><h2>Upcoming Events</h2><ul>';
1575
+ $visual .= $output;
1576
+ $visual .= '</ul></li>';
1577
+ return $visual;
1578
+ }
1579
+ }
1580
+ }
1581
+
1582
+ // Print todays events
1583
+ function todays_events()
1584
+ {
1585
+ global $wpdb;
1586
+
1587
+ // This function cannot be called unless calendar is up to date
1588
+ check_calendar();
1589
+
1590
+ // Find out if we should be displaying todays events
1591
+ $display = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='display_todays'",0,0);
1592
+
1593
+ if ($display == 'true')
1594
+ {
1595
+ $output = '<li class="todays-events"><h2>Todays Events</h2><ul>';
1596
+ $events = grab_events(date("Y"),date("m"),date("d"));
1597
+ usort($events, "time_cmp");
1598
+ foreach($events as $event)
1599
+ {
1600
+ if ($event->event_time == '00:00:00') {
1601
+ $time_string = ' all day';
1602
+ }
1603
+ else {
1604
+ $time_string = ' at '.date(get_option('time_format'), strtotime($event->event_time));
1605
+ }
1606
+ $output .= '<li>'.draw_widget_event($event).$time_string.'</li>';
1607
+ }
1608
+ $output .= '</ul></li>';
1609
+ if (count($events) != 0)
1610
+ {
1611
+ return $output;
1612
+ }
1613
+ }
1614
+ }
1615
+
1616
+ // Function to compare time in event objects
1617
+ function time_cmp($a, $b)
1618
+ {
1619
+ if ($a->event_time == $b->event_time) {
1620
+ return 0;
1621
+ }
1622
+ return ($a->event_time < $b->event_time) ? -1 : 1;
1623
+ }
1624
+
1625
+ // Used to draw multiple events
1626
+ function draw_events($events)
1627
+ {
1628
+ // We need to sort arrays of objects by time
1629
+ usort($events, "time_cmp");
1630
+
1631
+ // Now process the events
1632
+ foreach($events as $event)
1633
+ {
1634
+ $output .= draw_event($event);
1635
+ }
1636
+ return $output;
1637
+ }
1638
+
1639
+
1640
+ // The widget to show todays events in the sidebar
1641
+ function widget_init_calendar_today() {
1642
+ // Check for required functions
1643
+ if (!function_exists('register_sidebar_widget'))
1644
+ return;
1645
+
1646
+ function widget_calendar_today($args) {
1647
+ extract($args);
1648
+ ?>
1649
+ <?php echo todays_events(); ?>
1650
+ <?php
1651
+ }
1652
+
1653
+ register_sidebar_widget('Todays Events','widget_calendar_today');
1654
+ }
1655
+
1656
+ // The widget to show todays events in the sidebar
1657
+ function widget_init_calendar_upcoming() {
1658
+ // Check for required functions
1659
+ if (!function_exists('register_sidebar_widget'))
1660
+ return;
1661
+
1662
+ function widget_calendar_upcoming($args) {
1663
+ extract($args);
1664
+ ?>
1665
+ <?php echo upcoming_events(); ?>
1666
+ <?php
1667
+ }
1668
+
1669
+ register_sidebar_widget('Upcoming Events','widget_calendar_upcoming');
1670
+ }
1671
+
1672
+
1673
+ // Used to draw an event to the screen
1674
+ function draw_event($event)
1675
+ {
1676
+ global $wpdb;
1677
+
1678
+ // Calendar must be updated to run this function
1679
+ check_calendar();
1680
+
1681
+ // Before we do anything we want to know if we
1682
+ // should display the author and/or show categories.
1683
+ // We check for this later
1684
+ $display_author = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='display_author'",0,0);
1685
+ $show_cat = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='enable_categories'",0,0);
1686
+
1687
+ if ($show_cat == 'true')
1688
+ {
1689
+ $sql = "SELECT * FROM " . WP_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".$event->event_category;
1690
+ $cat_details = $wpdb->get_row($sql);
1691
+ $style = "background-color:".$cat_details->category_colour.";";
1692
+ }
1693
+
1694
+ $header_details .= '<div class="event-title">'.$event->event_title.'</div><div class="event-title-break"></div>';
1695
+ if ($event->event_time != "00:00:00")
1696
+ {
1697
+ $header_details .= '<strong>Time:</strong> ' . date(get_option('time_format'), strtotime($event->event_time)) . '<br />';
1698
+ }
1699
+ if ($display_author == 'true')
1700
+ {
1701
+ $e = get_userdata($event->event_author);
1702
+ $header_details .= '<strong>Posted by:</strong> '.$e->display_name.'<br />';
1703
+ }
1704
+ if ($display_author == 'true' || $event->event_time != "00:00:00")
1705
+ {
1706
+ $header_details .= '<div class="event-content-break"></div>';
1707
+ }
1708
+ if ($event->event_link != '') { $linky = $event->event_link; }
1709
+ else { $linky = '#'; }
1710
+
1711
+ $details = '<br />
1712
+ * <span class="calnk" nowrap="nowrap"><a href="'.$linky.'" style="'.$style.'">' . $event->event_title . '<span style="'.$style.'">' . $header_details . '' . $event->event_desc . '</span></a></span>';
1713
+
1714
+ return $details;
1715
+ }
1716
+
1717
+ // Draw an event but customise the HTML for use in the widget
1718
+ function draw_widget_event($event)
1719
+ {
1720
+ global $wpdb;
1721
+
1722
+ // Calendar must be updated to run this function
1723
+ check_calendar();
1724
+
1725
+ // Before we do anything we want to know if we
1726
+ // should display the author and/or show categories.
1727
+ // We check for this later
1728
+ $display_author = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='display_author'",0,0);
1729
+ $show_cat = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='enable_categories'",0,0);
1730
+
1731
+ if ($show_cat == 'true')
1732
+ {
1733
+ $sql = "SELECT * FROM " . WP_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".$event->event_category;
1734
+ $cat_details = $wpdb->get_row($sql);
1735
+ $style = "background-color:".$cat_details->category_colour.";";
1736
+ }
1737
+
1738
+ $header_details .= '<div class="event-title">'.$event->event_title.'</div><div class="event-title-break"></div>';
1739
+ if ($event->event_time != "00:00:00")
1740
+ {
1741
+ $header_details .= '<strong>Time:</strong> ' . date(get_option('time_format'), strtotime($event->event_time)) . '<br />';
1742
+ }
1743
+ if ($display_author == 'true')
1744
+ {
1745
+ $e = get_userdata($event->event_author);
1746
+ $header_details .= '<strong>Posted by:</strong> '.$e->display_name.'<br />';
1747
+ }
1748
+ if ($display_author == 'true' || $event->event_time != "00:00:00")
1749
+ {
1750
+ $header_details .= '<div class="event-content-break"></div>';
1751
+ }
1752
+ if ($event->event_link != '') { $linky = $event->event_link; }
1753
+ else { $linky = '#'; }
1754
+
1755
+ $details = '<span class="calnk" nowrap="nowrap"><a href="'.$linky.'">' . $event->event_title . '<span style="'.$style.'">' . $header_details . '' . $event->event_desc . '</span></a></span>';
1756
+
1757
+ return $details;
1758
+ }
1759
+
1760
+ // Grab all events for the requested date from calendar
1761
+ function grab_events($y,$m,$d)
1762
+ {
1763
+ global $wpdb;
1764
+
1765
+ $arr_events = array();
1766
+
1767
+ // Get the date format right
1768
+ $date = $y . '-' . $m . '-' . $d;
1769
+
1770
+ // Firstly we check for conventional events. These will form the first instance of a recurring event
1771
+ // or the only instance of a one-off event
1772
+ $events = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " WHERE event_begin <= '$date' AND event_end >= '$date' AND event_recur = 'S' ORDER BY event_id");
1773
+ if (!empty($events))
1774
+ {
1775
+ foreach($events as $event)
1776
+ {
1777
+ array_push($arr_events, $event);
1778
+ }
1779
+ }
1780
+
1781
+ // Even if there were results for that query, we may still have events recurring
1782
+ // from the past on this day. We now methodically check the for these events
1783
+
1784
+ /*
1785
+ The yearly code - easy because the day and month will be the same, so we return all yearly
1786
+ events that match the date part. Out of these we show those with a repeat of 0, and fast-foward
1787
+ a number of years for those with a value more than 0. Those that land in the future are displayed.
1788
+ */
1789
+
1790
+
1791
+ // Deal with forever recurring year events
1792
+ $events = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " WHERE event_recur = 'Y' AND EXTRACT(YEAR FROM '$date') >= EXTRACT(YEAR FROM event_begin) AND event_repeats = 0 ORDER BY event_id");
1793
+
1794
+ if (!empty($events))
1795
+ {
1796
+ foreach($events as $event)
1797
+ {
1798
+ // This is going to get complex so lets setup what we would place in for
1799
+ // an event so we can drop it in with ease
1800
+
1801
+ // Technically we don't care about the years, but we need to find out if the
1802
+ // event spans the turn of a year so we can deal with it appropriately.
1803
+ $year_begin = date('Y',strtotime($event->event_begin));
1804
+ $year_end = date('Y',strtotime($event->event_end));
1805
+
1806
+ if ($year_begin == $year_end)
1807
+ {
1808
+ if (date('m-d',strtotime($event->event_begin)) <= date('m-d',strtotime($date)) &&
1809
+ date('m-d',strtotime($event->event_end)) >= date('m-d',strtotime($date)))
1810
+ {
1811
+ array_push($arr_events, $event);
1812
+ }
1813
+ }
1814
+ else if ($year_begin < $year_end)
1815
+ {
1816
+ if (date('m-d',strtotime($event->event_begin)) <= date('m-d',strtotime($date)) ||
1817
+ date('m-d',strtotime($event->event_end)) >= date('m-d',strtotime($date)))
1818
+ {
1819
+ array_push($arr_events, $event);
1820
+ }
1821
+ }
1822
+ }
1823
+ }
1824
+
1825
+ // Now the ones that happen a finite number of times
1826
+ $events = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " WHERE event_recur = 'Y' AND EXTRACT(YEAR FROM '$date') >= EXTRACT(YEAR FROM event_begin) AND event_repeats != 0 AND (EXTRACT(YEAR FROM '$date')-EXTRACT(YEAR FROM event_begin)) <= event_repeats ORDER BY event_id");
1827
+ if (!empty($events))
1828
+ {
1829
+ foreach($events as $event)
1830
+ {
1831
+ // This is going to get complex so lets setup what we would place in for
1832
+ // an event so we can drop it in with ease
1833
+
1834
+ // Technically we don't care about the years, but we need to find out if the
1835
+ // event spans the turn of a year so we can deal with it appropriately.
1836
+ $year_begin = date('Y',strtotime($event->event_begin));
1837
+ $year_end = date('Y',strtotime($event->event_end));
1838
+
1839
+ if ($year_begin == $year_end)
1840
+ {
1841
+ if (date('m-d',strtotime($event->event_begin)) <= date('m-d',strtotime($date)) &&
1842
+ date('m-d',strtotime($event->event_end)) >= date('m-d',strtotime($date)))
1843
+ {
1844
+ array_push($arr_events, $event);
1845
+ }
1846
+ }
1847
+ else if ($year_begin < $year_end)
1848
+ {
1849
+ if (date('m-d',strtotime($event->event_begin)) <= date('m-d',strtotime($date)) ||
1850
+ date('m-d',strtotime($event->event_end)) >= date('m-d',strtotime($date)))
1851
+ {
1852
+ array_push($arr_events, $event);
1853
+ }
1854
+ }
1855
+ }
1856
+ }
1857
+
1858
+ /*
1859
+ The monthly code - just as easy because as long as the day of the month is correct, then we
1860
+ show the event
1861
+ */
1862
+
1863
+ // The monthly events that never stop recurring
1864
+ $events = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " WHERE event_recur = 'M' AND EXTRACT(YEAR FROM '$date') >= EXTRACT(YEAR FROM event_begin) AND event_repeats = 0 ORDER BY event_id");
1865
+ if (!empty($events))
1866
+ {
1867
+ foreach($events as $event)
1868
+ {
1869
+ // This is going to get complex so lets setup what we would place in for
1870
+ // an event so we can drop it in with ease
1871
+
1872
+ // Technically we don't care about the years or months, but we need to find out if the
1873
+ // event spans the turn of a year or month so we can deal with it appropriately.
1874
+ $month_begin = date('m',strtotime($event->event_begin));
1875
+ $month_end = date('m',strtotime($event->event_end));
1876
+
1877
+ if ($month_begin == $month_end)
1878
+ {
1879
+ if (date('d',strtotime($event->event_begin)) <= date('d',strtotime($date)) &&
1880
+ date('d',strtotime($event->event_end)) >= date('d',strtotime($date)))
1881
+ {
1882
+ array_push($arr_events, $event);
1883
+ }
1884
+ }
1885
+ else if ($month_begin < $month_end)
1886
+ {
1887
+ if ( ($event->event_begin <= date('Y-m-d',strtotime($date))) && (date('d',strtotime($event->event_begin)) <= date('d',strtotime($date)) ||
1888
+ date('d',strtotime($event->event_end)) >= date('d',strtotime($date))) )
1889
+ {
1890
+ array_push($arr_events, $event);
1891
+ }
1892
+ }
1893
+ }
1894
+ }
1895
+
1896
+
1897
+ // Now the ones that happen a finite number of times
1898
+ $events = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " WHERE event_recur = 'M' AND EXTRACT(YEAR FROM '$date') >= EXTRACT(YEAR FROM event_begin) AND event_repeats != 0 AND (PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM '$date'),EXTRACT(YEAR_MONTH FROM event_begin))) <= event_repeats ORDER BY event_id");
1899
+ if (!empty($events))
1900
+ {
1901
+ foreach($events as $event)
1902
+ {
1903
+ // This is going to get complex so lets setup what we would place in for
1904
+ // an event so we can drop it in with ease
1905
+
1906
+ // Technically we don't care about the years or months, but we need to find out if the
1907
+ // event spans the turn of a year or month so we can deal with it appropriately.
1908
+ $month_begin = date('m',strtotime($event->event_begin));
1909
+ $month_end = date('m',strtotime($event->event_end));
1910
+
1911
+ if ($month_begin == $month_end)
1912
+ {
1913
+ if (date('d',strtotime($event->event_begin)) <= date('d',strtotime($date)) &&
1914
+ date('d',strtotime($event->event_end)) >= date('d',strtotime($date)))
1915
+ {
1916
+ array_push($arr_events, $event);
1917
+ }
1918
+ }
1919
+ else if ($month_begin < $month_end)
1920
+ {
1921
+ if ( ($event->event_begin <= date('Y-m-d',strtotime($date))) && (date('d',strtotime($event->event_begin)) <= date('d',strtotime($date)) ||
1922
+ date('d',strtotime($event->event_end)) >= date('d',strtotime($date))) )
1923
+ {
1924
+ array_push($arr_events, $event);
1925
+ }
1926
+ }
1927
+ }
1928
+ }
1929
+
1930
+
1931
+ /*
1932
+ Weekly - well isn't this fun! We need to scan all weekly events, find what day they fell on
1933
+ and see if that matches the current day. If it does, we check to see if the repeats are 0.
1934
+ If they are, display the event, if not, we fast forward from the original day in week blocks
1935
+ until the number is exhausted. If the date we arrive at is in the future, display the event.
1936
+ */
1937
+
1938
+ // The weekly events that never stop recurring
1939
+ $events = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " WHERE event_recur = 'W' AND '$date' >= event_begin AND event_repeats = 0 ORDER BY event_id");
1940
+ if (!empty($events))
1941
+ {
1942
+ foreach($events as $event)
1943
+ {
1944
+ // This is going to get complex so lets setup what we would place in for
1945
+ // an event so we can drop it in with ease
1946
+
1947
+ // Now we are going to check to see what day the original event
1948
+ // fell on and see if the current date is both after it and on
1949
+ // the correct day. If it is, display the event!
1950
+ $day_start_event = date('D',strtotime($event->event_begin));
1951
+ $day_end_event = date('D',strtotime($event->event_end));
1952
+ $current_day = date('D',strtotime($date));
1953
+
1954
+ $plan = array();
1955
+ $plan['Mon'] = 1;
1956
+ $plan['Tue'] = 2;
1957
+ $plan['Wed'] = 3;
1958
+ $plan['Thu'] = 4;
1959
+ $plan['Fri'] = 5;
1960
+ $plan['Sat'] = 6;
1961
+ $plan['Sun'] = 7;
1962
+
1963
+ if ($plan[$day_start_event] > $plan[$day_end_event])
1964
+ {
1965
+ if (($plan[$day_start_event] <= $plan[$current_day]) || ($plan[$current_day] <= $plan[$day_end_event]))
1966
+ {
1967
+ array_push($arr_events, $event);
1968
+ }
1969
+ }
1970
+ else if (($plan[$day_start_event] < $plan[$day_end_event]) || ($plan[$day_start_event]== $plan[$day_end_event]))
1971
+ {
1972
+ if (($plan[$day_start_event] <= $plan[$current_day]) && ($plan[$current_day] <= $plan[$day_end_event]))
1973
+ {
1974
+ array_push($arr_events, $event);
1975
+ }
1976
+ }
1977
+
1978
+ }
1979
+ }
1980
+
1981
+ // The weekly events that have a limit on how many times they occur
1982
+ $events = $wpdb->get_results("SELECT * FROM " . WP_CALENDAR_TABLE . " WHERE event_recur = 'W' AND '$date' >= event_begin AND event_repeats != 0 AND (event_repeats*7) >= (TO_DAYS('$date') - TO_DAYS(event_end)) ORDER BY event_id");
1983
+ if (!empty($events))
1984
+ {
1985
+ foreach($events as $event)
1986
+ {
1987
+ // This is going to get complex so lets setup what we would place in for
1988
+ // an event so we can drop it in with ease
1989
+
1990
+ // Now we are going to check to see what day the original event
1991
+ // fell on and see if the current date is both after it and on
1992
+ // the correct day. If it is, display the event!
1993
+ $day_start_event = date('D',strtotime($event->event_begin));
1994
+ $day_end_event = date('D',strtotime($event->event_end));
1995
+ $current_day = date('D',strtotime($date));
1996
+
1997
+ $plan = array();
1998
+ $plan['Mon'] = 1;
1999
+ $plan['Tue'] = 2;
2000
+ $plan['Wed'] = 3;
2001
+ $plan['Thu'] = 4;
2002
+ $plan['Fri'] = 5;
2003
+ $plan['Sat'] = 6;
2004
+ $plan['Sun'] = 7;
2005
+
2006
+ if ($plan[$day_start_event] > $plan[$day_end_event])
2007
+ {
2008
+ if (($plan[$day_start_event] <= $plan[$current_day]) || ($plan[$current_day] <= $plan[$day_end_event]))
2009
+ {
2010
+ array_push($arr_events, $event);
2011
+ }
2012
+ }
2013
+ else if (($plan[$day_start_event] < $plan[$day_end_event]) || ($plan[$day_start_event]== $plan[$day_end_event]))
2014
+ {
2015
+ if (($plan[$day_start_event] <= $plan[$current_day]) && ($plan[$current_day] <= $plan[$day_end_event]))
2016
+ {
2017
+ array_push($arr_events, $event);
2018
+ }
2019
+ }
2020
+
2021
+ }
2022
+ }
2023
+
2024
+ return $arr_events;
2025
+ }
2026
+
2027
+
2028
+ // Actually do the printing of the calendar
2029
+ // Compared to searching for and displaying events
2030
+ // this bit is really rather easy!
2031
+ function calendar()
2032
+ {
2033
+ global $wpdb;
2034
+
2035
+ // First things first, make sure calendar is up to date
2036
+ check_calendar();
2037
+
2038
+ // Deal with the week not starting on a monday
2039
+ if (get_option('start_of_week') == 0)
2040
+ {
2041
+ $name_days = array(1=>'Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
2042
+ }
2043
+ // Choose Monday if anything other than Sunday is set
2044
+ else
2045
+ {
2046
+ $name_days = array(1=>'Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday');
2047
+ }
2048
+
2049
+ // Carry on with the script
2050
+ $name_months = array(1=>'January','February','March','April','May','June','July','August','September','October','November','December');
2051
+
2052
+ // If we don't pass arguments we want a calendar that is relevant to today
2053
+ if (empty($_GET['month']) || empty($_GET['yr']))
2054
+ {
2055
+ $c_year = date("Y");
2056
+ $c_month = date("m");
2057
+ $c_day = date("d");
2058
+ }
2059
+
2060
+ // Years get funny if we exceed 3000, so we use this check
2061
+ if ($_GET['yr'] <= 3000 && $_GET['yr'] >= 0)
2062
+ {
2063
+ // This is just plain nasty and all because of permalinks
2064
+ // which are no longer used, this will be cleaned up soon
2065
+ if ($_GET['month'] == 'jan' || $_GET['month'] == 'feb' || $_GET['month'] == 'mar' || $_GET['month'] == 'apr' || $_GET['month'] == 'may' || $_GET['month'] == 'jun' || $_GET['month'] == 'jul' || $_GET['month'] == 'aug' || $_GET['month'] == 'sept' || $_GET['month'] == 'oct' || $_GET['month'] == 'nov' || $_GET['month'] == 'dec')
2066
+ {
2067
+
2068
+ // Again nasty code to map permalinks into something
2069
+ // databases can understand. This will be cleaned up
2070
+ $c_year = mysql_escape_string($_GET['yr']);
2071
+ if ($_GET['month'] == 'jan') { $t_month = 1; }
2072
+ else if ($_GET['month'] == 'feb') { $t_month = 2; }
2073
+ else if ($_GET['month'] == 'mar') { $t_month = 3; }
2074
+ else if ($_GET['month'] == 'apr') { $t_month = 4; }
2075
+ else if ($_GET['month'] == 'may') { $t_month = 5; }
2076
+ else if ($_GET['month'] == 'jun') { $t_month = 6; }
2077
+ else if ($_GET['month'] == 'jul') { $t_month = 7; }
2078
+ else if ($_GET['month'] == 'aug') { $t_month = 8; }
2079
+ else if ($_GET['month'] == 'sept') { $t_month = 9; }
2080
+ else if ($_GET['month'] == 'oct') { $t_month = 10; }
2081
+ else if ($_GET['month'] == 'nov') { $t_month = 11; }
2082
+ else if ($_GET['month'] == 'dec') { $t_month = 12; }
2083
+ $c_month = $t_month;
2084
+ $c_day = date("d");
2085
+ }
2086
+ // No valid month causes the calendar to default to today
2087
+ else
2088
+ {
2089
+ $c_year = date("Y");
2090
+ $c_month = date("m");
2091
+ $c_day = date("d");
2092
+ }
2093
+ }
2094
+ // No valid year causes the calendar to default to today
2095
+ else
2096
+ {
2097
+ $c_year = date("Y");
2098
+ $c_month = date("m");
2099
+ $c_day = date("d");
2100
+ }
2101
+
2102
+ // Fix the days of the week if week start is not on a monday
2103
+ if (get_option('start_of_week') == 0)
2104
+ {
2105
+ $first_weekday = date("w",mktime(0,0,0,$c_month,1,$c_year));
2106
+ $first_weekday = ($first_weekday==0?1:$first_weekday+1);
2107
+ }
2108
+ // Otherwise assume the week starts on a Monday. Anything other
2109
+ // than Sunday or Monday is just plain odd
2110
+ else
2111
+ {
2112
+ $first_weekday = date("w",mktime(0,0,0,$c_month,1,$c_year));
2113
+ $first_weekday = ($first_weekday==0?7:$first_weekday);
2114
+ }
2115
+
2116
+ $days_in_month = date("t", mktime (0,0,0,$c_month,1,$c_year));
2117
+
2118
+ // Start the table and add the header and naviagtion
2119
+ $calendar_body .= '
2120
+ <table cellspacing="1" cellpadding="0" class="calendar-table">
2121
+ ';
2122
+
2123
+ // We want to know if we should display the date switcher
2124
+ $date_switcher = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='display_jump'",0,0);
2125
+
2126
+ if ($date_switcher == 'true')
2127
+ {
2128
+ $calendar_body .= '<tr>
2129
+ <td colspan="7" class="calendar-date-switcher">
2130
+ <form method="GET" action="'.$_SERVER['REQUEST_URI'].'">
2131
+ ';
2132
+ $qsa = array();
2133
+ parse_str($_SERVER['QUERY_STRING'],$qsa);
2134
+ foreach ($qsa as $name => $argument)
2135
+ {
2136
+ if ($name != 'month' && $name != 'yr')
2137
+ {
2138
+ $calendar_body .= '<input type="hidden" name="'.$name.'" value="'.$argument.'" />
2139
+ ';
2140
+ }
2141
+ }
2142
+ function month_comparison($month)
2143
+ {
2144
+ $current_month = strtolower(date("M", time()));
2145
+ if (isset($_GET['yr']) && isset($_GET['month']))
2146
+ {
2147
+ if ($month == $_GET['month'])
2148
+ {
2149
+ return ' selected="selected"';
2150
+ }
2151
+ }
2152
+ elseif ($month == $current_month)
2153
+ {
2154
+ return ' selected="selected"';
2155
+ }
2156
+ }
2157
+ // We build the months in the switcher
2158
+ $calendar_body .= '
2159
+ Month: <select name="month" style="width:100px;">
2160
+ <option value="jan"'.month_comparison('jan').'>January</option>
2161
+ <option value="feb"'.month_comparison('feb').'>February</option>
2162
+ <option value="mar"'.month_comparison('mar').'>March</option>
2163
+ <option value="apr"'.month_comparison('apr').'>April</option>
2164
+ <option value="may"'.month_comparison('may').'>May</option>
2165
+ <option value="jun"'.month_comparison('jun').'>June</option>
2166
+ <option value="jul"'.month_comparison('jul').'>July</option>
2167
+ <option value="aug"'.month_comparison('aug').'>August</option>
2168
+ <option value="sept"'.month_comparison('sept').'>September</option>
2169
+ <option value="oct"'.month_comparison('oct').'>October</option>
2170
+ <option value="nov"'.month_comparison('nov').'>November</option>
2171
+ <option value="dec"'.month_comparison('dec').'>December</option>
2172
+ </select>
2173
+ Year: <select name="yr" style="width:60px;">
2174
+ ';
2175
+
2176
+ // The year builder is string mania. If you can make sense of this,
2177
+ // you know your PHP!
2178
+ function year_comparison($year)
2179
+ {
2180
+ $current_year = strtolower(date("Y", time()));
2181
+ if (isset($_GET['yr']) && isset($_GET['month']))
2182
+ {
2183
+ if ($year == $_GET['yr'])
2184
+ {
2185
+ return ' selected="selected"';
2186
+ }
2187
+ }
2188
+ else if ($year == $current_year)
2189
+ {
2190
+ return ' selected="selected"';
2191
+ }
2192
+ }
2193
+
2194
+ $past = 30;
2195
+ $future = 30;
2196
+ $fut = 1;
2197
+ while ($past > 0)
2198
+ {
2199
+ $p .= ' <option value="';
2200
+ $p .= date("Y",time())-$past;
2201
+ $p .= '"'.year_comparison(date("Y",time())-$past).'>';
2202
+ $p .= date("Y",time())-$past.'</option>
2203
+ ';
2204
+ $past = $past - 1;
2205
+ }
2206
+ while ($fut < $future)
2207
+ {
2208
+ $f .= ' <option value="';
2209
+ $f .= date("Y",time())+$fut;
2210
+ $f .= '"'.year_comparison(date("Y",time())+$fut).'>';
2211
+ $f .= date("Y",time())+$fut.'</option>
2212
+ ';
2213
+ $fut = $fut + 1;
2214
+ }
2215
+ $calendar_body .= $p;
2216
+ $calendar_body .= ' <option value="'.date("Y",time()).'"'.year_comparison(date("Y",time())).'>'.date("Y",time()).'</option>
2217
+ ';
2218
+ $calendar_body .= $f;
2219
+ $calendar_body .= '</select>
2220
+ <input type="submit" value="Go" />
2221
+ </form>
2222
+ </td>
2223
+ </tr>
2224
+ ';
2225
+ }
2226
+
2227
+ // The header of the calendar table and the links. Note calls to link functions
2228
+ $calendar_body .= '<tr>
2229
+ <td colspan="7" class="calendar-heading">
2230
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
2231
+ <tr>
2232
+ <td class="calendar-prev">' . prev_link($c_year,$c_month) . '</td>
2233
+ <td class="calendar-month">'.$name_months[(int)$c_month].' '.$c_year.'</td>
2234
+ <td class="calendar-next">' . next_link($c_year,$c_month) . '</td>
2235
+ </tr>
2236
+ </table>
2237
+ </td>
2238
+ </tr>
2239
+ ';
2240
+
2241
+ // Print the headings of the days of the week
2242
+ $calendar_body .= '<tr>
2243
+ ';
2244
+ for ($i=1; $i<=7; $i++)
2245
+ {
2246
+ // Colours need to be different if the starting day of the week is different
2247
+ if (get_option('start_of_week') == 0)
2248
+ {
2249
+ $calendar_body .= ' <td class="'.($i<7&&$i>1?'normal-day-heading':'weekend-heading').'">'.$name_days[$i].'</td>
2250
+ ';
2251
+ }
2252
+ else
2253
+ {
2254
+ $calendar_body .= ' <td class="'.($i<6?'normal-day-heading':'weekend-heading').'">'.$name_days[$i].'</td>
2255
+ ';
2256
+ }
2257
+ }
2258
+ $calendar_body .= '</tr>
2259
+ ';
2260
+
2261
+ for ($i=1; $i<=$days_in_month;)
2262
+ {
2263
+ $calendar_body .= '<tr>
2264
+ ';
2265
+ for ($ii=1; $ii<=7; $ii++)
2266
+ {
2267
+ if ($ii==$first_weekday && $i==1)
2268
+ {
2269
+ $go = TRUE;
2270
+ }
2271
+ elseif ($i > $days_in_month )
2272
+ {
2273
+ $go = FALSE;
2274
+ }
2275
+
2276
+ if ($go)
2277
+ {
2278
+ // Colours again, this time for the day numbers
2279
+ if (get_option('start_of_week') == 0)
2280
+ {
2281
+ // This bit of code is for styles believe it or not.
2282
+ $grabbed_events = grab_events($c_year,$c_month,$i);
2283
+ $no_events_class = '';
2284
+ if (!count($grabbed_events))
2285
+ {
2286
+ $no_events_class = ' no-events';
2287
+ }
2288
+ $calendar_body .= ' <td class="'.(date("Ymd", mktime (0,0,0,$c_month,$i,$c_year))==date("Ymd")?'current-day':'day-with-date').$no_events_class.'"><span '.($ii<7&&$ii>1?'':'class="weekend"').'>'.$i++.'</span><span class="event">' . draw_events($grabbed_events) . '</span></td>
2289
+ ';
2290
+ }
2291
+ else
2292
+ {
2293
+ $grabbed_events = grab_events($c_year,$c_month,$i);
2294
+ $no_events_class = '';
2295
+ if (!count($grabbed_events))
2296
+ {
2297
+ $no_events_class = ' no-events';
2298
+ }
2299
+ $calendar_body .= ' <td class="'.(date("Ymd", mktime (0,0,0,$c_month,$i,$c_year))==date("Ymd")?'current-day':'day-with-date').$no_events_class.'"><span '.($ii<6?'':'class="weekend"').'>'.$i++.'</span><span class="event">' . draw_events($grabbed_events) . '</span></td>
2300
+ ';
2301
+ }
2302
+ }
2303
+ else
2304
+ {
2305
+ $calendar_body .= ' <td class="day-without-date">&nbsp;</td>
2306
+ ';
2307
+ }
2308
+ }
2309
+ $calendar_body .= '</tr>
2310
+ ';
2311
+ }
2312
+ $show_cat = $wpdb->get_var("SELECT config_value FROM ".WP_CALENDAR_CONFIG_TABLE." WHERE config_item='enable_categories'",0,0);
2313
+
2314
+ if ($show_cat == 'true')
2315
+ {
2316
+ $sql = "SELECT * FROM " . WP_CALENDAR_CATEGORIES_TABLE . " ORDER BY category_name ASC";
2317
+ $cat_details = $wpdb->get_results($sql);
2318
+ $calendar_body .= '<tr><td colspan="7">
2319
+ <table class="cat-key">
2320
+ <tr><td colspan="2"><strong>Category Key</strong></td></tr>
2321
+ ';
2322
+ foreach($cat_details as $cat_detail)
2323
+ {
2324
+ $calendar_body .= '<tr><td style="background-color:'.$cat_detail->category_colour.'; width:20px; height:20px;"></td><td>'.$cat_detail->category_name.'</td></tr>';
2325
+ }
2326
+ $calendar_body .= '</table>
2327
+ </td></tr>
2328
+ ';
2329
+ }
2330
+ $calendar_body .= '</table>
2331
+ ';
2332
+
2333
+ // A little link to yours truely. See the README if you wish to remove this
2334
+ $calendar_body .= '<div class="kjo-link"><p>Web development and hosting from <a href="http://www.kjowebservices.co.uk">KJO Web Services</a></p></div>
2335
+ ';
2336
+
2337
+ // Phew! After that bit of string building, spit it all out.
2338
+ // The actual printing is done by the calling function.
2339
+ return $calendar_body;
2340
+ }
2341
+
2342
+ ?>
javascript.js ADDED
@@ -0,0 +1,1463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ===================================================================
2
+ // Author: Matt Kruse <matt@mattkruse.com>
3
+ // WWW: http://www.mattkruse.com/
4
+ //
5
+ // NOTICE: You may use this code for any purpose, commercial or
6
+ // private, without any further permission from the author. You may
7
+ // remove this notice from your final code if you wish, however it is
8
+ // appreciated by the author if at least my web site address is kept.
9
+ //
10
+ // You may *NOT* re-distribute this code in any way except through its
11
+ // use. That means, you can include it in your product, or your web
12
+ // site, or any other form where the code is actually being used. You
13
+ // may not put the plain javascript up on your site for download or
14
+ // include it in your javascript libraries for download.
15
+ // If you wish to share this code with others, please just point them
16
+ // to the URL instead.
17
+ // Please DO NOT link directly to my .js files from your site. Copy
18
+ // the files to your server and use them there. Thank you.
19
+ // ===================================================================
20
+
21
+
22
+ /* SOURCE FILE: AnchorPosition.js */
23
+
24
+ /*
25
+ AnchorPosition.js
26
+ Author: Matt Kruse
27
+ Last modified: 10/11/02
28
+
29
+ DESCRIPTION: These functions find the position of an <A> tag in a document,
30
+ so other elements can be positioned relative to it.
31
+
32
+ COMPATABILITY: Netscape 4.x,6.x,Mozilla, IE 5.x,6.x on Windows. Some small
33
+ positioning errors - usually with Window positioning - occur on the
34
+ Macintosh platform.
35
+
36
+ FUNCTIONS:
37
+ getAnchorPosition(anchorname)
38
+ Returns an Object() having .x and .y properties of the pixel coordinates
39
+ of the upper-left corner of the anchor. Position is relative to the PAGE.
40
+
41
+ getAnchorWindowPosition(anchorname)
42
+ Returns an Object() having .x and .y properties of the pixel coordinates
43
+ of the upper-left corner of the anchor, relative to the WHOLE SCREEN.
44
+
45
+ NOTES:
46
+
47
+ 1) For popping up separate browser windows, use getAnchorWindowPosition.
48
+ Otherwise, use getAnchorPosition
49
+
50
+ 2) Your anchor tag MUST contain both NAME and ID attributes which are the
51
+ same. For example:
52
+ <A NAME="test" ID="test"> </A>
53
+
54
+ 3) There must be at least a space between <A> </A> for IE5.5 to see the
55
+ anchor tag correctly. Do not do <A></A> with no space.
56
+ */
57
+
58
+ // getAnchorPosition(anchorname)
59
+ // This function returns an object having .x and .y properties which are the coordinates
60
+ // of the named anchor, relative to the page.
61
+ function getAnchorPosition(anchorname) {
62
+ // This function will return an Object with x and y properties
63
+ var useWindow=false;
64
+ var coordinates=new Object();
65
+ var x=0,y=0;
66
+ // Browser capability sniffing
67
+ var use_gebi=false, use_css=false, use_layers=false;
68
+ if (document.getElementById) { use_gebi=true; }
69
+ else if (document.all) { use_css=true; }
70
+ else if (document.layers) { use_layers=true; }
71
+ // Logic to find position
72
+ if (use_gebi && document.all) {
73
+ x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
74
+ y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
75
+ }
76
+ else if (use_gebi) {
77
+ var o=document.getElementById(anchorname);
78
+ x=AnchorPosition_getPageOffsetLeft(o);
79
+ y=AnchorPosition_getPageOffsetTop(o);
80
+ }
81
+ else if (use_css) {
82
+ x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
83
+ y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
84
+ }
85
+ else if (use_layers) {
86
+ var found=0;
87
+ for (var i=0; i<document.anchors.length; i++) {
88
+ if (document.anchors[i].name==anchorname) { found=1; break; }
89
+ }
90
+ if (found==0) {
91
+ coordinates.x=0; coordinates.y=0; return coordinates;
92
+ }
93
+ x=document.anchors[i].x;
94
+ y=document.anchors[i].y;
95
+ }
96
+ else {
97
+ coordinates.x=0; coordinates.y=0; return coordinates;
98
+ }
99
+ coordinates.x=x;
100
+ coordinates.y=y;
101
+ return coordinates;
102
+ }
103
+
104
+ // getAnchorWindowPosition(anchorname)
105
+ // This function returns an object having .x and .y properties which are the coordinates
106
+ // of the named anchor, relative to the window
107
+ function getAnchorWindowPosition(anchorname) {
108
+ var coordinates=getAnchorPosition(anchorname);
109
+ var x=0;
110
+ var y=0;
111
+ if (document.getElementById) {
112
+ if (isNaN(window.screenX)) {
113
+ x=coordinates.x-document.body.scrollLeft+window.screenLeft;
114
+ y=coordinates.y-document.body.scrollTop+window.screenTop;
115
+ }
116
+ else {
117
+ x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
118
+ y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
119
+ }
120
+ }
121
+ else if (document.all) {
122
+ x=coordinates.x-document.body.scrollLeft+window.screenLeft;
123
+ y=coordinates.y-document.body.scrollTop+window.screenTop;
124
+ }
125
+ else if (document.layers) {
126
+ x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
127
+ y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
128
+ }
129
+ coordinates.x=x;
130
+ coordinates.y=y;
131
+ return coordinates;
132
+ }
133
+
134
+ // Functions for IE to get position of an object
135
+ function AnchorPosition_getPageOffsetLeft (el) {
136
+ var ol=el.offsetLeft;
137
+ while ((el=el.offsetParent) != null) { ol += el.offsetLeft; }
138
+ return ol;
139
+ }
140
+ function AnchorPosition_getWindowOffsetLeft (el) {
141
+ return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;
142
+ }
143
+ function AnchorPosition_getPageOffsetTop (el) {
144
+ var ot=el.offsetTop;
145
+ while((el=el.offsetParent) != null) { ot += el.offsetTop; }
146
+ return ot;
147
+ }
148
+ function AnchorPosition_getWindowOffsetTop (el) {
149
+ return AnchorPosition_getPageOffsetTop(el)-document.body.scrollTop;
150
+ }
151
+
152
+ /* SOURCE FILE: date.js */
153
+
154
+ // HISTORY
155
+ // ------------------------------------------------------------------
156
+ // May 17, 2003: Fixed bug in parseDate() for dates <1970
157
+ // March 11, 2003: Added parseDate() function
158
+ // March 11, 2003: Added "NNN" formatting option. Doesn't match up
159
+ // perfectly with SimpleDateFormat formats, but
160
+ // backwards-compatability was required.
161
+
162
+ // ------------------------------------------------------------------
163
+ // These functions use the same 'format' strings as the
164
+ // java.text.SimpleDateFormat class, with minor exceptions.
165
+ // The format string consists of the following abbreviations:
166
+ //
167
+ // Field | Full Form | Short Form
168
+ // -------------+--------------------+-----------------------
169
+ // Year | yyyy (4 digits) | yy (2 digits), y (2 or 4 digits)
170
+ // Month | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
171
+ // | NNN (abbr.) |
172
+ // Day of Month | dd (2 digits) | d (1 or 2 digits)
173
+ // Day of Week | EE (name) | E (abbr)
174
+ // Hour (1-12) | hh (2 digits) | h (1 or 2 digits)
175
+ // Hour (0-23) | HH (2 digits) | H (1 or 2 digits)
176
+ // Hour (0-11) | KK (2 digits) | K (1 or 2 digits)
177
+ // Hour (1-24) | kk (2 digits) | k (1 or 2 digits)
178
+ // Minute | mm (2 digits) | m (1 or 2 digits)
179
+ // Second | ss (2 digits) | s (1 or 2 digits)
180
+ // AM/PM | a |
181
+ //
182
+ // NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
183
+ // Examples:
184
+ // "MMM d, y" matches: January 01, 2000
185
+ // Dec 1, 1900
186
+ // Nov 20, 00
187
+ // "M/d/yy" matches: 01/20/00
188
+ // 9/2/00
189
+ // "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
190
+ // ------------------------------------------------------------------
191
+
192
+ var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
193
+ var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
194
+ function LZ(x) {return(x<0||x>9?"":"0")+x}
195
+
196
+ // ------------------------------------------------------------------
197
+ // isDate ( date_string, format_string )
198
+ // Returns true if date string matches format of format string and
199
+ // is a valid date. Else returns false.
200
+ // It is recommended that you trim whitespace around the value before
201
+ // passing it to this function, as whitespace is NOT ignored!
202
+ // ------------------------------------------------------------------
203
+ function isDate(val,format) {
204
+ var date=getDateFromFormat(val,format);
205
+ if (date==0) { return false; }
206
+ return true;
207
+ }
208
+
209
+ // -------------------------------------------------------------------
210
+ // compareDates(date1,date1format,date2,date2format)
211
+ // Compare two date strings to see which is greater.
212
+ // Returns:
213
+ // 1 if date1 is greater than date2
214
+ // 0 if date2 is greater than date1 of if they are the same
215
+ // -1 if either of the dates is in an invalid format
216
+ // -------------------------------------------------------------------
217
+ function compareDates(date1,dateformat1,date2,dateformat2) {
218
+ var d1=getDateFromFormat(date1,dateformat1);
219
+ var d2=getDateFromFormat(date2,dateformat2);
220
+ if (d1==0 || d2==0) {
221
+ return -1;
222
+ }
223
+ else if (d1 > d2) {
224
+ return 1;
225
+ }
226
+ return 0;
227
+ }
228
+
229
+ // ------------------------------------------------------------------
230
+ // formatDate (date_object, format)
231
+ // Returns a date in the output format specified.
232
+ // The format string uses the same abbreviations as in getDateFromFormat()
233
+ // ------------------------------------------------------------------
234
+ function formatDate(date,format) {
235
+ format=format+"";
236
+ var result="";
237
+ var i_format=0;
238
+ var c="";
239
+ var token="";
240
+ var y=date.getYear()+"";
241
+ var M=date.getMonth()+1;
242
+ var d=date.getDate();
243
+ var E=date.getDay();
244
+ var H=date.getHours();
245
+ var m=date.getMinutes();
246
+ var s=date.getSeconds();
247
+ var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
248
+ // Convert real date parts into formatted versions
249
+ var value=new Object();
250
+ if (y.length < 4) {y=""+(y-0+1900);}
251
+ value["y"]=""+y;
252
+ value["yyyy"]=y;
253
+ value["yy"]=y.substring(2,4);
254
+ value["M"]=M;
255
+ value["MM"]=LZ(M);
256
+ value["MMM"]=MONTH_NAMES[M-1];
257
+ value["NNN"]=MONTH_NAMES[M+11];
258
+ value["d"]=d;
259
+ value["dd"]=LZ(d);
260
+ value["E"]=DAY_NAMES[E+7];
261
+ value["EE"]=DAY_NAMES[E];
262
+ value["H"]=H;
263
+ value["HH"]=LZ(H);
264
+ if (H==0){value["h"]=12;}
265
+ else if (H>12){value["h"]=H-12;}
266
+ else {value["h"]=H;}
267
+ value["hh"]=LZ(value["h"]);
268
+ if (H>11){value["K"]=H-12;} else {value["K"]=H;}
269
+ value["k"]=H+1;
270
+ value["KK"]=LZ(value["K"]);
271
+ value["kk"]=LZ(value["k"]);
272
+ if (H > 11) { value["a"]="PM"; }
273
+ else { value["a"]="AM"; }
274
+ value["m"]=m;
275
+ value["mm"]=LZ(m);
276
+ value["s"]=s;
277
+ value["ss"]=LZ(s);
278
+ while (i_format < format.length) {
279
+ c=format.charAt(i_format);
280
+ token="";
281
+ while ((format.charAt(i_format)==c) && (i_format < format.length)) {
282
+ token += format.charAt(i_format++);
283
+ }
284
+ if (value[token] != null) { result=result + value[token]; }
285
+ else { result=result + token; }
286
+ }
287
+ return result;
288
+ }
289
+
290
+ // ------------------------------------------------------------------
291
+ // Utility functions for parsing in getDateFromFormat()
292
+ // ------------------------------------------------------------------
293
+ function _isInteger(val) {
294
+ var digits="1234567890";
295
+ for (var i=0; i < val.length; i++) {
296
+ if (digits.indexOf(val.charAt(i))==-1) { return false; }
297
+ }
298
+ return true;
299
+ }
300
+ function _getInt(str,i,minlength,maxlength) {
301
+ for (var x=maxlength; x>=minlength; x--) {
302
+ var token=str.substring(i,i+x);
303
+ if (token.length < minlength) { return null; }
304
+ if (_isInteger(token)) { return token; }
305
+ }
306
+ return null;
307
+ }
308
+
309
+ // ------------------------------------------------------------------
310
+ // getDateFromFormat( date_string , format_string )
311
+ //
312
+ // This function takes a date string and a format string. It matches
313
+ // If the date string matches the format string, it returns the
314
+ // getTime() of the date. If it does not match, it returns 0.
315
+ // ------------------------------------------------------------------
316
+ function getDateFromFormat(val,format) {
317
+ val=val+"";
318
+ format=format+"";
319
+ var i_val=0;
320
+ var i_format=0;
321
+ var c="";
322
+ var token="";
323
+ var token2="";
324
+ var x,y;
325
+ var now=new Date();
326
+ var year=now.getYear();
327
+ var month=now.getMonth()+1;
328
+ var date=1;
329
+ var hh=now.getHours();
330
+ var mm=now.getMinutes();
331
+ var ss=now.getSeconds();
332
+ var ampm="";
333
+
334
+ while (i_format < format.length) {
335
+ // Get next token from format string
336
+ c=format.charAt(i_format);
337
+ token="";
338
+ while ((format.charAt(i_format)==c) && (i_format < format.length)) {
339
+ token += format.charAt(i_format++);
340
+ }
341
+ // Extract contents of value based on format token
342
+ if (token=="yyyy" || token=="yy" || token=="y") {
343
+ if (token=="yyyy") { x=4;y=4; }
344
+ if (token=="yy") { x=2;y=2; }
345
+ if (token=="y") { x=2;y=4; }
346
+ year=_getInt(val,i_val,x,y);
347
+ if (year==null) { return 0; }
348
+ i_val += year.length;
349
+ if (year.length==2) {
350
+ if (year > 70) { year=1900+(year-0); }
351
+ else { year=2000+(year-0); }
352
+ }
353
+ }
354
+ else if (token=="MMM"||token=="NNN"){
355
+ month=0;
356
+ for (var i=0; i<MONTH_NAMES.length; i++) {
357
+ var month_name=MONTH_NAMES[i];
358
+ if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
359
+ if (token=="MMM"||(token=="NNN"&&i>11)) {
360
+ month=i+1;
361
+ if (month>12) { month -= 12; }
362
+ i_val += month_name.length;
363
+ break;
364
+ }
365
+ }
366
+ }
367
+ if ((month < 1)||(month>12)){return 0;}
368
+ }
369
+ else if (token=="EE"||token=="E"){
370
+ for (var i=0; i<DAY_NAMES.length; i++) {
371
+ var day_name=DAY_NAMES[i];
372
+ if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
373
+ i_val += day_name.length;
374
+ break;
375
+ }
376
+ }
377
+ }
378
+ else if (token=="MM"||token=="M") {
379
+ month=_getInt(val,i_val,token.length,2);
380
+ if(month==null||(month<1)||(month>12)){return 0;}
381
+ i_val+=month.length;}
382
+ else if (token=="dd"||token=="d") {
383
+ date=_getInt(val,i_val,token.length,2);
384
+ if(date==null||(date<1)||(date>31)){return 0;}
385
+ i_val+=date.length;}
386
+ else if (token=="hh"||token=="h") {
387
+ hh=_getInt(val,i_val,token.length,2);
388
+ if(hh==null||(hh<1)||(hh>12)){return 0;}
389
+ i_val+=hh.length;}
390
+ else if (token=="HH"||token=="H") {
391
+ hh=_getInt(val,i_val,token.length,2);
392
+ if(hh==null||(hh<0)||(hh>23)){return 0;}
393
+ i_val+=hh.length;}
394
+ else if (token=="KK"||token=="K") {
395
+ hh=_getInt(val,i_val,token.length,2);
396
+ if(hh==null||(hh<0)||(hh>11)){return 0;}
397
+ i_val+=hh.length;}
398
+ else if (token=="kk"||token=="k") {
399
+ hh=_getInt(val,i_val,token.length,2);
400
+ if(hh==null||(hh<1)||(hh>24)){return 0;}
401
+ i_val+=hh.length;hh--;}
402
+ else if (token=="mm"||token=="m") {
403
+ mm=_getInt(val,i_val,token.length,2);
404
+ if(mm==null||(mm<0)||(mm>59)){return 0;}
405
+ i_val+=mm.length;}
406
+ else if (token=="ss"||token=="s") {
407
+ ss=_getInt(val,i_val,token.length,2);
408
+ if(ss==null||(ss<0)||(ss>59)){return 0;}
409
+ i_val+=ss.length;}
410
+ else if (token=="a") {
411
+ if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
412
+ else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
413
+ else {return 0;}
414
+ i_val+=2;}
415
+ else {
416
+ if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
417
+ else {i_val+=token.length;}
418
+ }
419
+ }
420
+ // If there are any trailing characters left in the value, it doesn't match
421
+ if (i_val != val.length) { return 0; }
422
+ // Is date valid for month?
423
+ if (month==2) {
424
+ // Check for leap year
425
+ if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
426
+ if (date > 29){ return 0; }
427
+ }
428
+ else { if (date > 28) { return 0; } }
429
+ }
430
+ if ((month==4)||(month==6)||(month==9)||(month==11)) {
431
+ if (date > 30) { return 0; }
432
+ }
433
+ // Correct hours value
434
+ if (hh<12 && ampm=="PM") { hh=hh-0+12; }
435
+ else if (hh>11 && ampm=="AM") { hh-=12; }
436
+ var newdate=new Date(year,month-1,date,hh,mm,ss);
437
+ return newdate.getTime();
438
+ }
439
+
440
+ // ------------------------------------------------------------------
441
+ // parseDate( date_string [, prefer_euro_format] )
442
+ //
443
+ // This function takes a date string and tries to match it to a
444
+ // number of possible date formats to get the value. It will try to
445
+ // match against the following international formats, in this order:
446
+ // y-M-d MMM d, y MMM d,y y-MMM-d d-MMM-y MMM d
447
+ // M/d/y M-d-y M.d.y MMM-d M/d M-d
448
+ // d/M/y d-M-y d.M.y d-MMM d/M d-M
449
+ // A second argument may be passed to instruct the method to search
450
+ // for formats like d/M/y (european format) before M/d/y (American).
451
+ // Returns a Date object or null if no patterns match.
452
+ // ------------------------------------------------------------------
453
+ function parseDate(val) {
454
+ var preferEuro=(arguments.length==2)?arguments[1]:false;
455
+ generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
456
+ monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
457
+ dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
458
+ var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
459
+ var d=null;
460
+ for (var i=0; i<checkList.length; i++) {
461
+ var l=window[checkList[i]];
462
+ for (var j=0; j<l.length; j++) {
463
+ d=getDateFromFormat(val,l[j]);
464
+ if (d!=0) { return new Date(d); }
465
+ }
466
+ }
467
+ return null;
468
+ }
469
+
470
+ /* SOURCE FILE: PopupWindow.js */
471
+
472
+ /*
473
+ PopupWindow.js
474
+ Author: Matt Kruse
475
+ Last modified: 02/16/04
476
+
477
+ DESCRIPTION: This object allows you to easily and quickly popup a window
478
+ in a certain place. The window can either be a DIV or a separate browser
479
+ window.
480
+
481
+ COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
482
+ positioning errors - usually with Window positioning - occur on the
483
+ Macintosh platform. Due to bugs in Netscape 4.x, populating the popup
484
+ window with <STYLE> tags may cause errors.
485
+
486
+ USAGE:
487
+ // Create an object for a WINDOW popup
488
+ var win = new PopupWindow();
489
+
490
+ // Create an object for a DIV window using the DIV named 'mydiv'
491
+ var win = new PopupWindow('mydiv');
492
+
493
+ // Set the window to automatically hide itself when the user clicks
494
+ // anywhere else on the page except the popup
495
+ win.autoHide();
496
+
497
+ // Show the window relative to the anchor name passed in
498
+ win.showPopup(anchorname);
499
+
500
+ // Hide the popup
501
+ win.hidePopup();
502
+
503
+ // Set the size of the popup window (only applies to WINDOW popups
504
+ win.setSize(width,height);
505
+
506
+ // Populate the contents of the popup window that will be shown. If you
507
+ // change the contents while it is displayed, you will need to refresh()
508
+ win.populate(string);
509
+
510
+ // set the URL of the window, rather than populating its contents
511
+ // manually
512
+ win.setUrl("http://www.site.com/");
513
+
514
+ // Refresh the contents of the popup
515
+ win.refresh();
516
+
517
+ // Specify how many pixels to the right of the anchor the popup will appear
518
+ win.offsetX = 50;
519
+
520
+ // Specify how many pixels below the anchor the popup will appear
521
+ win.offsetY = 100;
522
+
523
+ NOTES:
524
+ 1) Requires the functions in AnchorPosition.js
525
+
526
+ 2) Your anchor tag MUST contain both NAME and ID attributes which are the
527
+ same. For example:
528
+ <A NAME="test" ID="test"> </A>
529
+
530
+ 3) There must be at least a space between <A> </A> for IE5.5 to see the
531
+ anchor tag correctly. Do not do <A></A> with no space.
532
+
533
+ 4) When a PopupWindow object is created, a handler for 'onmouseup' is
534
+ attached to any event handler you may have already defined. Do NOT define
535
+ an event handler for 'onmouseup' after you define a PopupWindow object or
536
+ the autoHide() will not work correctly.
537
+ */
538
+
539
+ // Set the position of the popup window based on the anchor
540
+ function PopupWindow_getXYPosition(anchorname) {
541
+ var coordinates;
542
+ if (this.type == "WINDOW") {
543
+ coordinates = getAnchorWindowPosition(anchorname);
544
+ }
545
+ else {
546
+ coordinates = getAnchorPosition(anchorname);
547
+ }
548
+ this.x = coordinates.x;
549
+ this.y = coordinates.y;
550
+ }
551
+ // Set width/height of DIV/popup window
552
+ function PopupWindow_setSize(width,height) {
553
+ this.width = width;
554
+ this.height = height;
555
+ }
556
+ // Fill the window with contents
557
+ function PopupWindow_populate(contents) {
558
+ this.contents = contents;
559
+ this.populated = false;
560
+ }
561
+ // Set the URL to go to
562
+ function PopupWindow_setUrl(url) {
563
+ this.url = url;
564
+ }
565
+ // Set the window popup properties
566
+ function PopupWindow_setWindowProperties(props) {
567
+ this.windowProperties = props;
568
+ }
569
+ // Refresh the displayed contents of the popup
570
+ function PopupWindow_refresh() {
571
+ if (this.divName != null) {
572
+ // refresh the DIV object
573
+ if (this.use_gebi) {
574
+ document.getElementById(this.divName).innerHTML = this.contents;
575
+ }
576
+ else if (this.use_css) {
577
+ document.all[this.divName].innerHTML = this.contents;
578
+ }
579
+ else if (this.use_layers) {
580
+ var d = document.layers[this.divName];
581
+ d.document.open();
582
+ d.document.writeln(this.contents);
583
+ d.document.close();
584
+ }
585
+ }
586
+ else {
587
+ if (this.popupWindow != null && !this.popupWindow.closed) {
588
+ if (this.url!="") {
589
+ this.popupWindow.location.href=this.url;
590
+ }
591
+ else {
592
+ this.popupWindow.document.open();
593
+ this.popupWindow.document.writeln(this.contents);
594
+ this.popupWindow.document.close();
595
+ }
596
+ this.popupWindow.focus();
597
+ }
598
+ }
599
+ }
600
+ // Position and show the popup, relative to an anchor object
601
+ function PopupWindow_showPopup(anchorname) {
602
+ this.getXYPosition(anchorname);
603
+ this.x += this.offsetX;
604
+ this.y += this.offsetY;
605
+ if (!this.populated && (this.contents != "")) {
606
+ this.populated = true;
607
+ this.refresh();
608
+ }
609
+ if (this.divName != null) {
610
+ // Show the DIV object
611
+ if (this.use_gebi) {
612
+ document.getElementById(this.divName).style.left = this.x + "px";
613
+ document.getElementById(this.divName).style.top = this.y + "px";
614
+ document.getElementById(this.divName).style.visibility = "visible";
615
+ }
616
+ else if (this.use_css) {
617
+ document.all[this.divName].style.left = this.x;
618
+ document.all[this.divName].style.top = this.y;
619
+ document.all[this.divName].style.visibility = "visible";
620
+ }
621
+ else if (this.use_layers) {
622
+ document.layers[this.divName].left = this.x;
623
+ document.layers[this.divName].top = this.y;
624
+ document.layers[this.divName].visibility = "visible";
625
+ }
626
+ }
627
+ else {
628
+ if (this.popupWindow == null || this.popupWindow.closed) {
629
+ // If the popup window will go off-screen, move it so it doesn't
630
+ if (this.x<0) { this.x=0; }
631
+ if (this.y<0) { this.y=0; }
632
+ if (screen && screen.availHeight) {
633
+ if ((this.y + this.height) > screen.availHeight) {
634
+ this.y = screen.availHeight - this.height;
635
+ }
636
+ }
637
+ if (screen && screen.availWidth) {
638
+ if ((this.x + this.width) > screen.availWidth) {
639
+ this.x = screen.availWidth - this.width;
640
+ }
641
+ }
642
+ var avoidAboutBlank = window.opera || ( document.layers && !navigator.mimeTypes['*'] ) || navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled );
643
+ this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");
644
+ }
645
+ this.refresh();
646
+ }
647
+ }
648
+ // Hide the popup
649
+ function PopupWindow_hidePopup() {
650
+ if (this.divName != null) {
651
+ if (this.use_gebi) {
652
+ document.getElementById(this.divName).style.visibility = "hidden";
653
+ }
654
+ else if (this.use_css) {
655
+ document.all[this.divName].style.visibility = "hidden";
656
+ }
657
+ else if (this.use_layers) {
658
+ document.layers[this.divName].visibility = "hidden";
659
+ }
660
+ }
661
+ else {
662
+ if (this.popupWindow && !this.popupWindow.closed) {
663
+ this.popupWindow.close();
664
+ this.popupWindow = null;
665
+ }
666
+ }
667
+ }
668
+ // Pass an event and return whether or not it was the popup DIV that was clicked
669
+ function PopupWindow_isClicked(e) {
670
+ if (this.divName != null) {
671
+ if (this.use_layers) {
672
+ var clickX = e.pageX;
673
+ var clickY = e.pageY;
674
+ var t = document.layers[this.divName];
675
+ if ((clickX > t.left) && (clickX < t.left+t.clip.width) && (clickY > t.top) && (clickY < t.top+t.clip.height)) {
676
+ return true;
677
+ }
678
+ else { return false; }
679
+ }
680
+ else if (document.all) { // Need to hard-code this to trap IE for error-handling
681
+ var t = window.event.srcElement;
682
+ while (t.parentElement != null) {
683
+ if (t.id==this.divName) {
684
+ return true;
685
+ }
686
+ t = t.parentElement;
687
+ }
688
+ return false;
689
+ }
690
+ else if (this.use_gebi && e) {
691
+ var t = e.originalTarget;
692
+ while (t.parentNode != null) {
693
+ if (t.id==this.divName) {
694
+ return true;
695
+ }
696
+ t = t.parentNode;
697
+ }
698
+ return false;
699
+ }
700
+ return false;
701
+ }
702
+ return false;
703
+ }
704
+
705
+ // Check an onMouseDown event to see if we should hide
706
+ function PopupWindow_hideIfNotClicked(e) {
707
+ if (this.autoHideEnabled && !this.isClicked(e)) {
708
+ this.hidePopup();
709
+ }
710
+ }
711
+ // Call this to make the DIV disable automatically when mouse is clicked outside it
712
+ function PopupWindow_autoHide() {
713
+ this.autoHideEnabled = true;
714
+ }
715
+ // This global function checks all PopupWindow objects onmouseup to see if they should be hidden
716
+ function PopupWindow_hidePopupWindows(e) {
717
+ for (var i=0; i<popupWindowObjects.length; i++) {
718
+ if (popupWindowObjects[i] != null) {
719
+ var p = popupWindowObjects[i];
720
+ p.hideIfNotClicked(e);
721
+ }
722
+ }
723
+ }
724
+ // Run this immediately to attach the event listener
725
+ function PopupWindow_attachListener() {
726
+ if (document.layers) {
727
+ document.captureEvents(Event.MOUSEUP);
728
+ }
729
+ window.popupWindowOldEventListener = document.onmouseup;
730
+ if (window.popupWindowOldEventListener != null) {
731
+ document.onmouseup = new Function("window.popupWindowOldEventListener(); PopupWindow_hidePopupWindows();");
732
+ }
733
+ else {
734
+ document.onmouseup = PopupWindow_hidePopupWindows;
735
+ }
736
+ }
737
+ // CONSTRUCTOR for the PopupWindow object
738
+ // Pass it a DIV name to use a DHTML popup, otherwise will default to window popup
739
+ function PopupWindow() {
740
+ if (!window.popupWindowIndex) { window.popupWindowIndex = 0; }
741
+ if (!window.popupWindowObjects) { window.popupWindowObjects = new Array(); }
742
+ if (!window.listenerAttached) {
743
+ window.listenerAttached = true;
744
+ PopupWindow_attachListener();
745
+ }
746
+ this.index = popupWindowIndex++;
747
+ popupWindowObjects[this.index] = this;
748
+ this.divName = null;
749
+ this.popupWindow = null;
750
+ this.width=0;
751
+ this.height=0;
752
+ this.populated = false;
753
+ this.visible = false;
754
+ this.autoHideEnabled = false;
755
+
756
+ this.contents = "";
757
+ this.url="";
758
+ this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";
759
+ if (arguments.length>0) {
760
+ this.type="DIV";
761
+ this.divName = arguments[0];
762
+ }
763
+ else {
764
+ this.type="WINDOW";
765
+ }
766
+ this.use_gebi = false;
767
+ this.use_css = false;
768
+ this.use_layers = false;
769
+ if (document.getElementById) { this.use_gebi = true; }
770
+ else if (document.all) { this.use_css = true; }
771
+ else if (document.layers) { this.use_layers = true; }
772
+ else { this.type = "WINDOW"; }
773
+ this.offsetX = 0;
774
+ this.offsetY = 0;
775
+ // Method mappings
776
+ this.getXYPosition = PopupWindow_getXYPosition;
777
+ this.populate = PopupWindow_populate;
778
+ this.setUrl = PopupWindow_setUrl;
779
+ this.setWindowProperties = PopupWindow_setWindowProperties;
780
+ this.refresh = PopupWindow_refresh;
781
+ this.showPopup = PopupWindow_showPopup;
782
+ this.hidePopup = PopupWindow_hidePopup;
783
+ this.setSize = PopupWindow_setSize;
784
+ this.isClicked = PopupWindow_isClicked;
785
+ this.autoHide = PopupWindow_autoHide;
786
+ this.hideIfNotClicked = PopupWindow_hideIfNotClicked;
787
+ }
788
+
789
+ /* SOURCE FILE: CalendarPopup.js */
790
+
791
+ // HISTORY
792
+ // ------------------------------------------------------------------
793
+ // Feb 7, 2005: Fixed a CSS styles to use px unit
794
+ // March 29, 2004: Added check in select() method for the form field
795
+ // being disabled. If it is, just return and don't do anything.
796
+ // March 24, 2004: Fixed bug - when month name and abbreviations were
797
+ // changed, date format still used original values.
798
+ // January 26, 2004: Added support for drop-down month and year
799
+ // navigation (Thanks to Chris Reid for the idea)
800
+ // September 22, 2003: Fixed a minor problem in YEAR calendar with
801
+ // CSS prefix.
802
+ // August 19, 2003: Renamed the function to get styles, and made it
803
+ // work correctly without an object reference
804
+ // August 18, 2003: Changed showYearNavigation and
805
+ // showYearNavigationInput to optionally take an argument of
806
+ // true or false
807
+ // July 31, 2003: Added text input option for year navigation.
808
+ // Added a per-calendar CSS prefix option to optionally use
809
+ // different styles for different calendars.
810
+ // July 29, 2003: Fixed bug causing the Today link to be clickable
811
+ // even though today falls in a disabled date range.
812
+ // Changed formatting to use pure CSS, allowing greater control
813
+ // over look-and-feel options.
814
+ // June 11, 2003: Fixed bug causing the Today link to be unselectable
815
+ // under certain cases when some days of week are disabled
816
+ // March 14, 2003: Added ability to disable individual dates or date
817
+ // ranges, display as light gray and strike-through
818
+ // March 14, 2003: Removed dependency on graypixel.gif and instead
819
+ /// use table border coloring
820
+ // March 12, 2003: Modified showCalendar() function to allow optional
821
+ // start-date parameter
822
+ // March 11, 2003: Modified select() function to allow optional
823
+ // start-date parameter
824
+ /*
825
+ DESCRIPTION: This object implements a popup calendar to allow the user to
826
+ select a date, month, quarter, or year.
827
+
828
+ COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
829
+ positioning errors - usually with Window positioning - occur on the
830
+ Macintosh platform.
831
+ The calendar can be modified to work for any location in the world by
832
+ changing which weekday is displayed as the first column, changing the month
833
+ names, and changing the column headers for each day.
834
+
835
+ USAGE:
836
+ // Create a new CalendarPopup object of type WINDOW
837
+ var cal = new CalendarPopup();
838
+
839
+ // Create a new CalendarPopup object of type DIV using the DIV named 'mydiv'
840
+ var cal = new CalendarPopup('mydiv');
841
+
842
+ // Easy method to link the popup calendar with an input box.
843
+ cal.select(inputObject, anchorname, dateFormat);
844
+ // Same method, but passing a default date other than the field's current value
845
+ cal.select(inputObject, anchorname, dateFormat, '01/02/2000');
846
+ // This is an example call to the popup calendar from a link to populate an
847
+ // input box. Note that to use this, date.js must also be included!!
848
+ <A HREF="#" onClick="cal.select(document.forms[0].date,'anchorname','MM/dd/yyyy'); return false;">Select</A>
849
+
850
+ // Set the type of date select to be used. By default it is 'date'.
851
+ cal.setDisplayType(type);
852
+
853
+ // When a date, month, quarter, or year is clicked, a function is called and
854
+ // passed the details. You must write this function, and tell the calendar
855
+ // popup what the function name is.
856
+ // Function to be called for 'date' select receives y, m, d
857
+ cal.setReturnFunction(functionname);
858
+ // Function to be called for 'month' select receives y, m
859
+ cal.setReturnMonthFunction(functionname);
860
+ // Function to be called for 'quarter' select receives y, q
861
+ cal.setReturnQuarterFunction(functionname);
862
+ // Function to be called for 'year' select receives y
863
+ cal.setReturnYearFunction(functionname);
864
+
865
+ // Show the calendar relative to a given anchor
866
+ cal.showCalendar(anchorname);
867
+
868
+ // Hide the calendar. The calendar is set to autoHide automatically
869
+ cal.hideCalendar();
870
+
871
+ // Set the month names to be used. Default are English month names
872
+ cal.setMonthNames("January","February","March",...);
873
+
874
+ // Set the month abbreviations to be used. Default are English month abbreviations
875
+ cal.setMonthAbbreviations("Jan","Feb","Mar",...);
876
+
877
+ // Show navigation for changing by the year, not just one month at a time
878
+ cal.showYearNavigation();
879
+
880
+ // Show month and year dropdowns, for quicker selection of month of dates
881
+ cal.showNavigationDropdowns();
882
+
883
+ // Set the text to be used above each day column. The days start with
884
+ // sunday regardless of the value of WeekStartDay
885
+ cal.setDayHeaders("S","M","T",...);
886
+
887
+ // Set the day for the first column in the calendar grid. By default this
888
+ // is Sunday (0) but it may be changed to fit the conventions of other
889
+ // countries.
890
+ cal.setWeekStartDay(1); // week is Monday - Sunday
891
+
892
+ // Set the weekdays which should be disabled in the 'date' select popup. You can
893
+ // then allow someone to only select week end dates, or Tuedays, for example
894
+ cal.setDisabledWeekDays(0,1); // To disable selecting the 1st or 2nd days of the week
895
+
896
+ // Selectively disable individual days or date ranges. Disabled days will not
897
+ // be clickable, and show as strike-through text on current browsers.
898
+ // Date format is any format recognized by parseDate() in date.js
899
+ // Pass a single date to disable:
900
+ cal.addDisabledDates("2003-01-01");
901
+ // Pass null as the first parameter to mean "anything up to and including" the
902
+ // passed date:
903
+ cal.addDisabledDates(null, "01/02/03");
904
+ // Pass null as the second parameter to mean "including the passed date and
905
+ // anything after it:
906
+ cal.addDisabledDates("Jan 01, 2003", null);
907
+ // Pass two dates to disable all dates inbetween and including the two
908
+ cal.addDisabledDates("January 01, 2003", "Dec 31, 2003");
909
+
910
+ // When the 'year' select is displayed, set the number of years back from the
911
+ // current year to start listing years. Default is 2.
912
+ // This is also used for year drop-down, to decide how many years +/- to display
913
+ cal.setYearSelectStartOffset(2);
914
+
915
+ // Text for the word "Today" appearing on the calendar
916
+ cal.setTodayText("Today");
917
+
918
+ // The calendar uses CSS classes for formatting. If you want your calendar to
919
+ // have unique styles, you can set the prefix that will be added to all the
920
+ // classes in the output.
921
+ // For example, normal output may have this:
922
+ // <SPAN CLASS="cpTodayTextDisabled">Today<SPAN>
923
+ // But if you set the prefix like this:
924
+ cal.setCssPrefix("Test");
925
+ // The output will then look like:
926
+ // <SPAN CLASS="TestcpTodayTextDisabled">Today<SPAN>
927
+ // And you can define that style somewhere in your page.
928
+
929
+ // When using Year navigation, you can make the year be an input box, so
930
+ // the user can manually change it and jump to any year
931
+ cal.showYearNavigationInput();
932
+
933
+ // Set the calendar offset to be different than the default. By default it
934
+ // will appear just below and to the right of the anchorname. So if you have
935
+ // a text box where the date will go and and anchor immediately after the
936
+ // text box, the calendar will display immediately under the text box.
937
+ cal.offsetX = 20;
938
+ cal.offsetY = 20;
939
+
940
+ NOTES:
941
+ 1) Requires the functions in AnchorPosition.js and PopupWindow.js
942
+
943
+ 2) Your anchor tag MUST contain both NAME and ID attributes which are the
944
+ same. For example:
945
+ <A NAME="test" ID="test"> </A>
946
+
947
+ 3) There must be at least a space between <A> </A> for IE5.5 to see the
948
+ anchor tag correctly. Do not do <A></A> with no space.
949
+
950
+ 4) When a CalendarPopup object is created, a handler for 'onmouseup' is
951
+ attached to any event handler you may have already defined. Do NOT define
952
+ an event handler for 'onmouseup' after you define a CalendarPopup object
953
+ or the autoHide() will not work correctly.
954
+
955
+ 5) The calendar popup display uses style sheets to make it look nice.
956
+
957
+ */
958
+
959
+ // CONSTRUCTOR for the CalendarPopup Object
960
+ function CalendarPopup() {
961
+ var c;
962
+ if (arguments.length>0) {
963
+ c = new PopupWindow(arguments[0]);
964
+ }
965
+ else {
966
+ c = new PopupWindow();
967
+ c.setSize(150,175);
968
+ }
969
+ c.offsetX = -152;
970
+ c.offsetY = 25;
971
+ c.autoHide();
972
+ // Calendar-specific properties
973
+ c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
974
+ c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
975
+ c.dayHeaders = new Array("S","M","T","W","T","F","S");
976
+ c.returnFunction = "CP_tmpReturnFunction";
977
+ c.returnMonthFunction = "CP_tmpReturnMonthFunction";
978
+ c.returnQuarterFunction = "CP_tmpReturnQuarterFunction";
979
+ c.returnYearFunction = "CP_tmpReturnYearFunction";
980
+ c.weekStartDay = 0;
981
+ c.isShowYearNavigation = false;
982
+ c.displayType = "date";
983
+ c.disabledWeekDays = new Object();
984
+ c.disabledDatesExpression = "";
985
+ c.yearSelectStartOffset = 2;
986
+ c.currentDate = null;
987
+ c.todayText="Today";
988
+ c.cssPrefix="";
989
+ c.isShowNavigationDropdowns=false;
990
+ c.isShowYearNavigationInput=false;
991
+ window.CP_calendarObject = null;
992
+ window.CP_targetInput = null;
993
+ window.CP_dateFormat = "MM/dd/yyyy";
994
+ // Method mappings
995
+ c.copyMonthNamesToWindow = CP_copyMonthNamesToWindow;
996
+ c.setReturnFunction = CP_setReturnFunction;
997
+ c.setReturnMonthFunction = CP_setReturnMonthFunction;
998
+ c.setReturnQuarterFunction = CP_setReturnQuarterFunction;
999
+ c.setReturnYearFunction = CP_setReturnYearFunction;
1000
+ c.setMonthNames = CP_setMonthNames;
1001
+ c.setMonthAbbreviations = CP_setMonthAbbreviations;
1002
+ c.setDayHeaders = CP_setDayHeaders;
1003
+ c.setWeekStartDay = CP_setWeekStartDay;
1004
+ c.setDisplayType = CP_setDisplayType;
1005
+ c.setDisabledWeekDays = CP_setDisabledWeekDays;
1006
+ c.addDisabledDates = CP_addDisabledDates;
1007
+ c.setYearSelectStartOffset = CP_setYearSelectStartOffset;
1008
+ c.setTodayText = CP_setTodayText;
1009
+ c.showYearNavigation = CP_showYearNavigation;
1010
+ c.showCalendar = CP_showCalendar;
1011
+ c.hideCalendar = CP_hideCalendar;
1012
+ c.getStyles = getCalendarStyles;
1013
+ c.refreshCalendar = CP_refreshCalendar;
1014
+ c.getCalendar = CP_getCalendar;
1015
+ c.select = CP_select;
1016
+ c.setCssPrefix = CP_setCssPrefix;
1017
+ c.showNavigationDropdowns = CP_showNavigationDropdowns;
1018
+ c.showYearNavigationInput = CP_showYearNavigationInput;
1019
+ c.copyMonthNamesToWindow();
1020
+ // Return the object
1021
+ return c;
1022
+ }
1023
+ function CP_copyMonthNamesToWindow() {
1024
+ // Copy these values over to the date.js
1025
+ if (typeof(window.MONTH_NAMES)!="undefined" && window.MONTH_NAMES!=null) {
1026
+ window.MONTH_NAMES = new Array();
1027
+ for (var i=0; i<this.monthNames.length; i++) {
1028
+ window.MONTH_NAMES[window.MONTH_NAMES.length] = this.monthNames[i];
1029
+ }
1030
+ for (var i=0; i<this.monthAbbreviations.length; i++) {
1031
+ window.MONTH_NAMES[window.MONTH_NAMES.length] = this.monthAbbreviations[i];
1032
+ }
1033
+ }
1034
+ }
1035
+ // Temporary default functions to be called when items clicked, so no error is thrown
1036
+ function CP_tmpReturnFunction(y,m,d) {
1037
+ if (window.CP_targetInput!=null) {
1038
+ var dt = new Date(y,m-1,d,0,0,0);
1039
+ if (window.CP_calendarObject!=null) { window.CP_calendarObject.copyMonthNamesToWindow(); }
1040
+ window.CP_targetInput.value = formatDate(dt,window.CP_dateFormat);
1041
+ }
1042
+ else {
1043
+ alert('Use setReturnFunction() to define which function will get the clicked results!');
1044
+ }
1045
+ }
1046
+ function CP_tmpReturnMonthFunction(y,m) {
1047
+ alert('Use setReturnMonthFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , month='+m);
1048
+ }
1049
+ function CP_tmpReturnQuarterFunction(y,q) {
1050
+ alert('Use setReturnQuarterFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , quarter='+q);
1051
+ }
1052
+ function CP_tmpReturnYearFunction(y) {
1053
+ alert('Use setReturnYearFunction() to define which function will get the clicked results!\nYou clicked: year='+y);
1054
+ }
1055
+
1056
+ // Set the name of the functions to call to get the clicked item
1057
+ function CP_setReturnFunction(name) { this.returnFunction = name; }
1058
+ function CP_setReturnMonthFunction(name) { this.returnMonthFunction = name; }
1059
+ function CP_setReturnQuarterFunction(name) { this.returnQuarterFunction = name; }
1060
+ function CP_setReturnYearFunction(name) { this.returnYearFunction = name; }
1061
+
1062
+ // Over-ride the built-in month names
1063
+ function CP_setMonthNames() {
1064
+ for (var i=0; i<arguments.length; i++) { this.monthNames[i] = arguments[i]; }
1065
+ this.copyMonthNamesToWindow();
1066
+ }
1067
+
1068
+ // Over-ride the built-in month abbreviations
1069
+ function CP_setMonthAbbreviations() {
1070
+ for (var i=0; i<arguments.length; i++) { this.monthAbbreviations[i] = arguments[i]; }
1071
+ this.copyMonthNamesToWindow();
1072
+ }
1073
+
1074
+ // Over-ride the built-in column headers for each day
1075
+ function CP_setDayHeaders() {
1076
+ for (var i=0; i<arguments.length; i++) { this.dayHeaders[i] = arguments[i]; }
1077
+ }
1078
+
1079
+ // Set the day of the week (0-7) that the calendar display starts on
1080
+ // This is for countries other than the US whose calendar displays start on Monday(1), for example
1081
+ function CP_setWeekStartDay(day) { this.weekStartDay = day; }
1082
+
1083
+ // Show next/last year navigation links
1084
+ function CP_showYearNavigation() { this.isShowYearNavigation = (arguments.length>0)?arguments[0]:true; }
1085
+
1086
+ // Which type of calendar to display
1087
+ function CP_setDisplayType(type) {
1088
+ if (type!="date"&&type!="week-end"&&type!="month"&&type!="quarter"&&type!="year") { alert("Invalid display type! Must be one of: date,week-end,month,quarter,year"); return false; }
1089
+ this.displayType=type;
1090
+ }
1091
+
1092
+ // How many years back to start by default for year display
1093
+ function CP_setYearSelectStartOffset(num) { this.yearSelectStartOffset=num; }
1094
+
1095
+ // Set which weekdays should not be clickable
1096
+ function CP_setDisabledWeekDays() {
1097
+ this.disabledWeekDays = new Object();
1098
+ for (var i=0; i<arguments.length; i++) { this.disabledWeekDays[arguments[i]] = true; }
1099
+ }
1100
+
1101
+ // Disable individual dates or ranges
1102
+ // Builds an internal logical test which is run via eval() for efficiency
1103
+ function CP_addDisabledDates(start, end) {
1104
+ if (arguments.length==1) { end=start; }
1105
+ if (start==null && end==null) { return; }
1106
+ if (this.disabledDatesExpression!="") { this.disabledDatesExpression+= "||"; }
1107
+ if (start!=null) { start = parseDate(start); start=""+start.getFullYear()+LZ(start.getMonth()+1)+LZ(start.getDate());}
1108
+ if (end!=null) { end=parseDate(end); end=""+end.getFullYear()+LZ(end.getMonth()+1)+LZ(end.getDate());}
1109
+ if (start==null) { this.disabledDatesExpression+="(ds<="+end+")"; }
1110
+ else if (end ==null) { this.disabledDatesExpression+="(ds>="+start+")"; }
1111
+ else { this.disabledDatesExpression+="(ds>="+start+"&&ds<="+end+")"; }
1112
+ }
1113
+
1114
+ // Set the text to use for the "Today" link
1115
+ function CP_setTodayText(text) {
1116
+ this.todayText = text;
1117
+ }
1118
+
1119
+ // Set the prefix to be added to all CSS classes when writing output
1120
+ function CP_setCssPrefix(val) {
1121
+ this.cssPrefix = val;
1122
+ }
1123
+
1124
+ // Show the navigation as an dropdowns that can be manually changed
1125
+ function CP_showNavigationDropdowns() { this.isShowNavigationDropdowns = (arguments.length>0)?arguments[0]:true; }
1126
+
1127
+ // Show the year navigation as an input box that can be manually changed
1128
+ function CP_showYearNavigationInput() { this.isShowYearNavigationInput = (arguments.length>0)?arguments[0]:true; }
1129
+
1130
+ // Hide a calendar object
1131
+ function CP_hideCalendar() {
1132
+ if (arguments.length > 0) { window.popupWindowObjects[arguments[0]].hidePopup(); }
1133
+ else { this.hidePopup(); }
1134
+ }
1135
+
1136
+ // Refresh the contents of the calendar display
1137
+ function CP_refreshCalendar(index) {
1138
+ var calObject = window.popupWindowObjects[index];
1139
+ if (arguments.length>1) {
1140
+ calObject.populate(calObject.getCalendar(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]));
1141
+ }
1142
+ else {
1143
+ calObject.populate(calObject.getCalendar());
1144
+ }
1145
+ calObject.refresh();
1146
+ }
1147
+
1148
+ // Populate the calendar and display it
1149
+ function CP_showCalendar(anchorname) {
1150
+ if (arguments.length>1) {
1151
+ if (arguments[1]==null||arguments[1]=="") {
1152
+ this.currentDate=new Date();
1153
+ }
1154
+ else {
1155
+ this.currentDate=new Date(parseDate(arguments[1]));
1156
+ }
1157
+ }
1158
+ this.populate(this.getCalendar());
1159
+ this.showPopup(anchorname);
1160
+ }
1161
+
1162
+ // Simple method to interface popup calendar with a text-entry box
1163
+ function CP_select(inputobj, linkname, format) {
1164
+ var selectedDate=(arguments.length>3)?arguments[3]:null;
1165
+ if (!window.getDateFromFormat) {
1166
+ alert("calendar.select: To use this method you must also include 'date.js' for date formatting");
1167
+ return;
1168
+ }
1169
+ if (this.displayType!="date"&&this.displayType!="week-end") {
1170
+ alert("calendar.select: This function can only be used with displayType 'date' or 'week-end'");
1171
+ return;
1172
+ }
1173
+ if (inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea") {
1174
+ alert("calendar.select: Input object passed is not a valid form input object");
1175
+ window.CP_targetInput=null;
1176
+ return;
1177
+ }
1178
+ if (inputobj.disabled) { return; } // Can't use calendar input on disabled form input!
1179
+ window.CP_targetInput = inputobj;
1180
+ window.CP_calendarObject = this;
1181
+ this.currentDate=null;
1182
+ var time=0;
1183
+ if (selectedDate!=null) {
1184
+ time = getDateFromFormat(selectedDate,format)
1185
+ }
1186
+ else if (inputobj.value!="") {
1187
+ time = getDateFromFormat(inputobj.value,format);
1188
+ }
1189
+ if (selectedDate!=null || inputobj.value!="") {
1190
+ if (time==0) { this.currentDate=null; }
1191
+ else { this.currentDate=new Date(time); }
1192
+ }
1193
+ window.CP_dateFormat = format;
1194
+ this.showCalendar(linkname);
1195
+ }
1196
+
1197
+ // Get style block needed to display the calendar correctly
1198
+ function getCalendarStyles() {
1199
+ var result = "";
1200
+ var p = "";
1201
+ if (this!=null && typeof(this.cssPrefix)!="undefined" && this.cssPrefix!=null && this.cssPrefix!="") { p=this.cssPrefix; }
1202
+ result += "<STYLE>\n";
1203
+ result += "."+p+"cpYearNavigation,."+p+"cpMonthNavigation { background-color:#C0C0C0; text-align:center; vertical-align:center; text-decoration:none; color:#000000; font-weight:bold; }\n";
1204
+ result += "."+p+"cpDayColumnHeader, ."+p+"cpYearNavigation,."+p+"cpMonthNavigation,."+p+"cpCurrentMonthDate,."+p+"cpCurrentMonthDateDisabled,."+p+"cpOtherMonthDate,."+p+"cpOtherMonthDateDisabled,."+p+"cpCurrentDate,."+p+"cpCurrentDateDisabled,."+p+"cpTodayText,."+p+"cpTodayTextDisabled,."+p+"cpText { font-family:arial; font-size:8pt; }\n";
1205
+ result += "TD."+p+"cpDayColumnHeader { text-align:right; border:solid thin #C0C0C0;border-width:0px 0px 1px 0px; }\n";
1206
+ result += "."+p+"cpCurrentMonthDate, ."+p+"cpOtherMonthDate, ."+p+"cpCurrentDate { text-align:right; text-decoration:none; }\n";
1207
+ result += "."+p+"cpCurrentMonthDateDisabled, ."+p+"cpOtherMonthDateDisabled, ."+p+"cpCurrentDateDisabled { color:#D0D0D0; text-align:right; text-decoration:line-through; }\n";
1208
+ result += "."+p+"cpCurrentMonthDate, .cpCurrentDate { color:#000000; }\n";
1209
+ result += "."+p+"cpOtherMonthDate { color:#808080; }\n";
1210
+ result += "TD."+p+"cpCurrentDate { color:white; background-color: #C0C0C0; border-width:1px; border:solid thin #800000; }\n";
1211
+ result += "TD."+p+"cpCurrentDateDisabled { border-width:1px; border:solid thin #FFAAAA; }\n";
1212
+ result += "TD."+p+"cpTodayText, TD."+p+"cpTodayTextDisabled { border:solid thin #C0C0C0; border-width:1px 0px 0px 0px;}\n";
1213
+ result += "A."+p+"cpTodayText, SPAN."+p+"cpTodayTextDisabled { height:20px; }\n";
1214
+ result += "A."+p+"cpTodayText { color:black; }\n";
1215
+ result += "."+p+"cpTodayTextDisabled { color:#D0D0D0; }\n";
1216
+ result += "."+p+"cpBorder { border:solid thin #808080; }\n";
1217
+ result += "</STYLE>\n";
1218
+ return result;
1219
+ }
1220
+
1221
+ // Return a string containing all the calendar code to be displayed
1222
+ function CP_getCalendar() {
1223
+ var now = new Date();
1224
+ // Reference to window
1225
+ if (this.type == "WINDOW") { var windowref = "window.opener."; }
1226
+ else { var windowref = ""; }
1227
+ var result = "";
1228
+ // If POPUP, write entire HTML document
1229
+ if (this.type == "WINDOW") {
1230
+ result += "<HTML><HEAD><TITLE>Calendar</TITLE>"+this.getStyles()+"</HEAD><BODY MARGINWIDTH=0 MARGINHEIGHT=0 TOPMARGIN=0 RIGHTMARGIN=0 LEFTMARGIN=0>\n";
1231
+ result += '<CENTER><TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>\n';
1232
+ }
1233
+ else {
1234
+ result += '<TABLE CLASS="'+this.cssPrefix+'cpBorder" WIDTH=144 BORDER=1 BORDERWIDTH=1 CELLSPACING=0 CELLPADDING=1>\n';
1235
+ result += '<TR><TD ALIGN=CENTER>\n';
1236
+ result += '<CENTER>\n';
1237
+ }
1238
+ // Code for DATE display (default)
1239
+ // -------------------------------
1240
+ if (this.displayType=="date" || this.displayType=="week-end") {
1241
+ if (this.currentDate==null) { this.currentDate = now; }
1242
+ if (arguments.length > 0) { var month = arguments[0]; }
1243
+ else { var month = this.currentDate.getMonth()+1; }
1244
+ if (arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]) { var year = arguments[1]; }
1245
+ else { var year = this.currentDate.getFullYear(); }
1246
+ var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
1247
+ if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) {
1248
+ daysinmonth[2] = 29;
1249
+ }
1250
+ var current_month = new Date(year,month-1,1);
1251
+ var display_year = year;
1252
+ var display_month = month;
1253
+ var display_date = 1;
1254
+ var weekday= current_month.getDay();
1255
+ var offset = 0;
1256
+
1257
+ offset = (weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ;
1258
+ if (offset > 0) {
1259
+ display_month--;
1260
+ if (display_month < 1) { display_month = 12; display_year--; }
1261
+ display_date = daysinmonth[display_month]-offset+1;
1262
+ }
1263
+ var next_month = month+1;
1264
+ var next_month_year = year;
1265
+ if (next_month > 12) { next_month=1; next_month_year++; }
1266
+ var last_month = month-1;
1267
+ var last_month_year = year;
1268
+ if (last_month < 1) { last_month=12; last_month_year--; }
1269
+ var date_class;
1270
+ if (this.type!="WINDOW") {
1271
+ result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
1272
+ }
1273
+ result += '<TR>\n';
1274
+ var refresh = windowref+'CP_refreshCalendar';
1275
+ var refreshLink = 'javascript:' + refresh;
1276
+ if (this.isShowNavigationDropdowns) {
1277
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="78" COLSPAN="3"><select CLASS="'+this.cssPrefix+'cpMonthNavigation" name="cpMonth" onChange="'+refresh+'('+this.index+',this.options[this.selectedIndex].value-0,'+(year-0)+');">';
1278
+ for( var monthCounter=1; monthCounter<=12; monthCounter++ ) {
1279
+ var selected = (monthCounter==month) ? 'SELECTED' : '';
1280
+ result += '<option value="'+monthCounter+'" '+selected+'>'+this.monthNames[monthCounter-1]+'</option>';
1281
+ }
1282
+ result += '</select></TD>';
1283
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';
1284
+
1285
+ result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="56" COLSPAN="3"><select CLASS="'+this.cssPrefix+'cpYearNavigation" name="cpYear" onChange="'+refresh+'('+this.index+','+month+',this.options[this.selectedIndex].value-0);">';
1286
+ for( var yearCounter=year-this.yearSelectStartOffset; yearCounter<=year+this.yearSelectStartOffset; yearCounter++ ) {
1287
+ var selected = (yearCounter==year) ? 'SELECTED' : '';
1288
+ result += '<option value="'+yearCounter+'" '+selected+'>'+yearCounter+'</option>';
1289
+ }
1290
+ result += '</select></TD>';
1291
+ }
1292
+ else {
1293
+ if (this.isShowYearNavigation) {
1294
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+last_month+','+last_month_year+');">&lt;</A></TD>';
1295
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="58"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+'</SPAN></TD>';
1296
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+next_month+','+next_month_year+');">&gt;</A></TD>';
1297
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';
1298
+
1299
+ result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refreshLink+'('+this.index+','+month+','+(year-1)+');">&lt;</A></TD>';
1300
+ if (this.isShowYearNavigationInput) {
1301
+ result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><INPUT NAME="cpYear" CLASS="'+this.cssPrefix+'cpYearNavigation" SIZE="4" MAXLENGTH="4" VALUE="'+year+'" onBlur="'+refresh+'('+this.index+','+month+',this.value-0);"></TD>';
1302
+ }
1303
+ else {
1304
+ result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><SPAN CLASS="'+this.cssPrefix+'cpYearNavigation">'+year+'</SPAN></TD>';
1305
+ }
1306
+ result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refreshLink+'('+this.index+','+month+','+(year+1)+');">&gt;</A></TD>';
1307
+ }
1308
+ else {
1309
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+last_month+','+last_month_year+');">&lt;&lt;</A></TD>\n';
1310
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="100"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+' '+year+'</SPAN></TD>\n';
1311
+ result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+next_month+','+next_month_year+');">&gt;&gt;</A></TD>\n';
1312
+ }
1313
+ }
1314
+ result += '</TR></TABLE>\n';
1315
+ result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=0 CELLPADDING=1 ALIGN=CENTER>\n';
1316
+ result += '<TR>\n';
1317
+ for (var j=0; j<7; j++) {
1318
+
1319
+ result += '<TD CLASS="'+this.cssPrefix+'cpDayColumnHeader" WIDTH="14%"><SPAN CLASS="'+this.cssPrefix+'cpDayColumnHeader">'+this.dayHeaders[(this.weekStartDay+j)%7]+'</TD>\n';
1320
+ }
1321
+ result += '</TR>\n';
1322
+ for (var row=1; row<=6; row++) {
1323
+ result += '<TR>\n';
1324
+ for (var col=1; col<=7; col++) {
1325
+ var disabled=false;
1326
+ if (this.disabledDatesExpression!="") {
1327
+ var ds=""+display_year+LZ(display_month)+LZ(display_date);
1328
+ eval("disabled=("+this.disabledDatesExpression+")");
1329
+ }
1330
+ var dateClass = "";
1331
+ if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) {
1332
+ dateClass = "cpCurrentDate";
1333
+ }
1334
+ else if (display_month == month) {
1335
+ dateClass = "cpCurrentMonthDate";
1336
+ }
1337
+ else {
1338
+ dateClass = "cpOtherMonthDate";
1339
+ }
1340
+ if (disabled || this.disabledWeekDays[col-1]) {
1341
+ result += ' <TD CLASS="'+this.cssPrefix+dateClass+'"><SPAN CLASS="'+this.cssPrefix+dateClass+'Disabled">'+display_date+'</SPAN></TD>\n';
1342
+ }
1343
+ else {
1344
+ var selected_date = display_date;
1345
+ var selected_month = display_month;
1346
+ var selected_year = display_year;
1347
+ if (this.displayType=="week-end") {
1348
+ var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0);
1349
+ d.setDate(d.getDate() + (7-col));
1350
+ selected_year = d.getYear();
1351
+ if (selected_year < 1000) { selected_year += 1900; }
1352
+ selected_month = d.getMonth()+1;
1353
+ selected_date = d.getDate();
1354
+ }
1355
+ result += ' <TD CLASS="'+this.cssPrefix+dateClass+'"><A HREF="javascript:'+windowref+this.returnFunction+'('+selected_year+','+selected_month+','+selected_date+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+this.cssPrefix+dateClass+'">'+display_date+'</A></TD>\n';
1356
+ }
1357
+ display_date++;
1358
+ if (display_date > daysinmonth[display_month]) {
1359
+ display_date=1;
1360
+ display_month++;
1361
+ }
1362
+ if (display_month > 12) {
1363
+ display_month=1;
1364
+ display_year++;
1365
+ }
1366
+ }
1367
+ result += '</TR>';
1368
+ }
1369
+ var current_weekday = now.getDay() - this.weekStartDay;
1370
+ if (current_weekday < 0) {
1371
+ current_weekday += 7;
1372
+ }
1373
+ result += '<TR>\n';
1374
+ result += ' <TD COLSPAN=7 ALIGN=CENTER CLASS="'+this.cssPrefix+'cpTodayText">\n';
1375
+ if (this.disabledDatesExpression!="") {
1376
+ var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate());
1377
+ eval("disabled=("+this.disabledDatesExpression+")");
1378
+ }
1379
+ if (disabled || this.disabledWeekDays[current_weekday+1]) {
1380
+ result += ' <SPAN CLASS="'+this.cssPrefix+'cpTodayTextDisabled">'+this.todayText+'</SPAN>\n';
1381
+ }
1382
+ else {
1383
+ result += ' <A CLASS="'+this.cssPrefix+'cpTodayText" HREF="javascript:'+windowref+this.returnFunction+'(\''+now.getFullYear()+'\',\''+(now.getMonth()+1)+'\',\''+now.getDate()+'\');'+windowref+'CP_hideCalendar(\''+this.index+'\');">'+this.todayText+'</A>\n';
1384
+ }
1385
+ result += ' <BR>\n';
1386
+ result += ' </TD></TR></TABLE></CENTER></TD></TR></TABLE>\n';
1387
+ }
1388
+
1389
+ // Code common for MONTH, QUARTER, YEAR
1390
+ // ------------------------------------
1391
+ if (this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year") {
1392
+ if (arguments.length > 0) { var year = arguments[0]; }
1393
+ else {
1394
+ if (this.displayType=="year") { var year = now.getFullYear()-this.yearSelectStartOffset; }
1395
+ else { var year = now.getFullYear(); }
1396
+ }
1397
+ if (this.displayType!="year" && this.isShowYearNavigation) {
1398
+ result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
1399
+ result += '<TR>\n';
1400
+ result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-1)+');">&lt;&lt;</A></TD>\n';
1401
+ result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="100">'+year+'</TD>\n';
1402
+ result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+1)+');">&gt;&gt;</A></TD>\n';
1403
+ result += '</TR></TABLE>\n';
1404
+ }
1405
+ }
1406
+
1407
+ // Code for MONTH display
1408
+ // ----------------------
1409
+ if (this.displayType=="month") {
1410
+ // If POPUP, write entire HTML document
1411
+ result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
1412
+ for (var i=0; i<4; i++) {
1413
+ result += '<TR>';
1414
+ for (var j=0; j<3; j++) {
1415
+ var monthindex = ((i*3)+j);
1416
+ result += '<TD WIDTH=33% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnMonthFunction+'('+year+','+(monthindex+1)+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+this.monthAbbreviations[monthindex]+'</A></TD>';
1417
+ }
1418
+ result += '</TR>';
1419
+ }
1420
+ result += '</TABLE></CENTER></TD></TR></TABLE>\n';
1421
+ }
1422
+
1423
+ // Code for QUARTER display
1424
+ // ------------------------
1425
+ if (this.displayType=="quarter") {
1426
+ result += '<BR><TABLE WIDTH=120 BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN=CENTER>\n';
1427
+ for (var i=0; i<2; i++) {
1428
+ result += '<TR>';
1429
+ for (var j=0; j<2; j++) {
1430
+ var quarter = ((i*2)+j+1);
1431
+ result += '<TD WIDTH=50% ALIGN=CENTER><BR><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnQuarterFunction+'('+year+','+quarter+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">Q'+quarter+'</A><BR><BR></TD>';
1432
+ }
1433
+ result += '</TR>';
1434
+ }
1435
+ result += '</TABLE></CENTER></TD></TR></TABLE>\n';
1436
+ }
1437
+
1438
+ // Code for YEAR display
1439
+ // ---------------------
1440
+ if (this.displayType=="year") {
1441
+ var yearColumnSize = 4;
1442
+ result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
1443
+ result += '<TR>\n';
1444
+ result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-(yearColumnSize*2))+');">&lt;&lt;</A></TD>\n';
1445
+ result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+(yearColumnSize*2))+');">&gt;&gt;</A></TD>\n';
1446
+ result += '</TR></TABLE>\n';
1447
+ result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
1448
+ for (var i=0; i<yearColumnSize; i++) {
1449
+ for (var j=0; j<2; j++) {
1450
+ var currentyear = year+(j*yearColumnSize)+i;
1451
+ result += '<TD WIDTH=50% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnYearFunction+'('+currentyear+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+currentyear+'</A></TD>';
1452
+ }
1453
+ result += '</TR>';
1454
+ }
1455
+ result += '</TABLE></CENTER></TD></TR></TABLE>\n';
1456
+ }
1457
+ // Common
1458
+ if (this.type == "WINDOW") {
1459
+ result += "</BODY></HTML>\n";
1460
+ }
1461
+ return result;
1462
+ }
1463
+
readme.txt ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Calendar ===
2
+ Contributors: KieranOShea
3
+ Donate link: http://www.kjowebservices.co.uk
4
+ Tags: calendar, dates, times, events
5
+ Requires at least: 2.0
6
+ Tested up to: 2.6.1
7
+ Stable tag: 1.2
8
+
9
+ A simple but effective Calendar plugin for WordPress that allows you to
10
+ manage your events and appointments and display them to the world.
11
+
12
+ == Description ==
13
+
14
+ A simple but effective Calendar plugin for WordPress that allows you to
15
+ manage your events and appointments and display them to the world on your
16
+ website.
17
+
18
+ Features:
19
+
20
+ * Monthly view of events
21
+ * Mouse-over details for each event
22
+ * Events can have a timestamp (optional)
23
+ * Events can display their author (optional)
24
+ * Events can span more than one day
25
+ * Multiple events per day possible
26
+ * Events can repeat on a weekly, monthly or yearly basis
27
+ * Repeats can occur indefinitely or a limited number of times
28
+ * Easy to use events manager in admin dashboard
29
+ * Sidebar function/Widget to show todays events
30
+ * Sidebar function/Widget to show upcoming events
31
+ * Comprehensive options panel for admin
32
+ * Modifiable CSS using the options panel
33
+ * Optional drop down boxes to quickly change month and year
34
+ * User groups other than admin can be permitted to manage events
35
+ * Events can be placed into categories
36
+ * Categories system can be switched on or off
37
+ * Pop up javascript calendars help the choosing of dates
38
+ * Events can be links pointing to a location of your choice
39
+
40
+ == Installation ==
41
+
42
+ The installation is extremely simple and straightforward. It only takes a second.
43
+
44
+ Installing:
45
+
46
+ 1. Upload the whole calendar directory into your WordPress plugins directory.
47
+
48
+ 2. Activate the plugin on your WordPress plugins page
49
+
50
+ 3. Configure Calendar using:
51
+
52
+ Calendar -> Manage Events
53
+
54
+ Calendar -> Manage Categories
55
+
56
+ Calendar -> Calendar Options
57
+
58
+ 4. Edit or create a page on your blog which includes the text {CALENDAR} and visit
59
+ the page you have edited or created page. You should see your calendar in action.
60
+
61
+ Upgrading from 1.1:
62
+
63
+ 1. Deactivate the plugin (you will not lose any events)
64
+
65
+ 2. Remove the Rewrite rules from your .htaccess file that you added
66
+ when you first installed Calendar.
67
+
68
+ 3. Delete plugins/calendar.php, wp-admin/edit-calendar.php, wp-calendar.php
69
+
70
+ 4. Upload the whole calendar directory into your WordPress plugins directory.
71
+
72
+ 5. Activate the plugin on your WordPress plugins page
73
+
74
+ 6. Configure Calendar using:
75
+
76
+ Calendar -> Manage Events
77
+
78
+ Calendar -> Manage Categories
79
+
80
+ Calendar -> Calendar Options
81
+
82
+ 7. Edit or create a page on your blog which includes the text {CALENDAR} and visit
83
+ the page you have edited or created page. You should see your calendar in action.
84
+
85
+ Uninstalling:
86
+
87
+ 1. Deactivate the plugin on the plugins page of your blog dashboard
88
+
89
+ 2. Delete the uploaded files for the plugin
90
+
91
+ 3. Remove the text {CALENDAR} from the page you were using to show calendar, or delete that page
92
+
93
+ == Frequently Asked Questions ==
94
+
95
+ = Where are the frequently asked questions for Calendar? =
96
+
97
+ They are located on the [KJO Web Services forum](http://forum.kjowebservices.co.uk/viewtopic.php?f=13&t=10 "KJO Web Services forum")
98
+
99
+ = Where can I get support for the plugin? =
100
+
101
+ Support via e-mail became too much of a burden and the lack of e-mail
102
+ notifications made monitoring the WordPress forums impossible. There
103
+ is now a support area for Calendar on the [KJO Web Services forum](http://forum.kjowebservices.co.uk/viewtopic.php?f=13 "KJO Web Services forum")
104
+ which will be monitored and is the only official place to get support for Calendar.
105
+
106
+ = Can I remove the link to your company? =
107
+
108
+ Yes, you may do this, but please only do so if you absolutely have to (for
109
+ instance if you are using Calendar for a business site). Calendar is
110
+ popular and the business we get from users of Calendar deciding to comission
111
+ web work is what allows us to continue to provide Calendar free and open source.
112
+
113
+ == Screenshots ==
114
+
115
+ 1. Calendar being used on a blog page
116
+
117
+ 2. Widgets showing in the sidebar
118
+
119
+ 3. The event management screen of calendar
120
+
121
+ 4. The category management screen of calendar
122
+
123
+ 5. The options screen of Calendar
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
screenshot-3.png ADDED
Binary file
screenshot-4.png ADDED
Binary file
screenshot-5.png ADDED
Binary file