Events Manager - Version 2.0b1

Version Description

Download this release

Release Info

Developer nutsmuggler
Plugin Icon 128x128 Events Manager
Version 2.0b1
Comparing to
See all releases

Code changes from version 1.0.1 to 2.0b1

Files changed (81) hide show
  1. FirePHPCore/FirePHP.class.php +1375 -0
  2. FirePHPCore/LICENSE +29 -0
  3. FirePHPCore/fb.php +246 -0
  4. dbem-recurrence.php +266 -0
  5. dbem.js +32 -0
  6. dbem_UI_helpers.php +93 -0
  7. dbem_calendar.php +47 -25
  8. dbem_events.php +1832 -0
  9. dbem_global_map.js +108 -0
  10. dbem_locations.php +708 -0
  11. dbem_people.php +221 -0
  12. dbem_rsvp.php +379 -0
  13. dbem_single_location_map.js +32 -0
  14. events-manager.php +435 -1246
  15. events_manager.css +99 -0
  16. images/calendar-16.png +0 -0
  17. images/calendar-32.png +0 -0
  18. js/jquery-autocomplete/changelog.txt +20 -0
  19. js/jquery-autocomplete/jquery.autocomplete.css +48 -0
  20. js/jquery-autocomplete/jquery.autocomplete.min.js +15 -0
  21. js/jquery-autocomplete/jquery.autocomplete.pack.js +13 -0
  22. js/jquery-autocomplete/lib/jquery.ajaxQueue.js +116 -0
  23. js/jquery-autocomplete/lib/jquery.bgiframe.min.js +10 -0
  24. js/jquery-autocomplete/todo +166 -0
  25. js/jquery-ui-datepicker/ui.datepicker.css +213 -0
  26. js/jquery-ui-datepicker/ui.datepicker.js +1674 -0
  27. js/timeentry/jquery.timeentry-de.js +9 -0
  28. js/timeentry/jquery.timeentry-es.js +9 -0
  29. js/timeentry/jquery.timeentry-fr.js +9 -0
  30. js/timeentry/jquery.timeentry-hu.js +9 -0
  31. js/timeentry/jquery.timeentry-it.js +9 -0
  32. js/timeentry/jquery.timeentry-nl.js +9 -0
  33. js/timeentry/jquery.timeentry-pl.js +9 -0
  34. js/timeentry/jquery.timeentry-pt.js +9 -0
  35. js/timeentry/jquery.timeentry-ro.js +9 -0
  36. js/timeentry/jquery.timeentry-ru.js +9 -0
  37. js/timeentry/jquery.timeentry-sk.js +9 -0
  38. js/timeentry/jquery.timeentry-sv.js +9 -0
  39. js/timeentry/jquery.timeentry-tr.js +9 -0
  40. js/timeentry/jquery.timeentry-zh-CN.js +9 -0
  41. js/timeentry/jquery.timeentry.compat-1.2.6.js +77 -0
  42. js/timeentry/jquery.timeentry.css +8 -0
  43. js/timeentry/jquery.timeentry.ent +22 -0
  44. js/timeentry/jquery.timeentry.js +900 -0
  45. js/timeentry/jquery.timeentry.min.js +7 -0
  46. js/timeentry/jquery.timeentry.pack.js +7 -0
  47. js/timeentry/timeEntry.png +0 -0
  48. js/timeentry/timeEntry2.png +0 -0
  49. js/timeentry/timeEntry3.png +0 -0
  50. js/timeentry/timeEntry4.png +0 -0
  51. js/timeentry/timeEntry5.png +0 -0
  52. js/timeentry/timeEntry6.png +0 -0
  53. dbem-it_IT.mo → langs/dbem-es_ES.mo +0 -0
  54. dbem-it_IT.po → langs/dbem-es_ES.po +87 -87
  55. langs/dbem-it_IT.mo +0 -0
  56. langs/dbem-it_IT.po +1132 -0
  57. locations-search.php +29 -0
  58. phpmailer/class.phpmailer.php +1506 -0
  59. phpmailer/class.smtp.php +1045 -0
  60. phpmailer/dbem_phpmailer.php +47 -0
  61. phpmailer/language/phpmailer.lang-br.php +21 -0
  62. phpmailer/language/phpmailer.lang-ca.php +22 -0
  63. phpmailer/language/phpmailer.lang-cz.php +24 -0
  64. phpmailer/language/phpmailer.lang-de.php +23 -0
  65. phpmailer/language/phpmailer.lang-dk.php +24 -0
  66. phpmailer/language/phpmailer.lang-en.php +23 -0
  67. phpmailer/language/phpmailer.lang-es.php +23 -0
  68. phpmailer/language/phpmailer.lang-fi.php +23 -0
  69. phpmailer/language/phpmailer.lang-fo.php +25 -0
  70. phpmailer/language/phpmailer.lang-fr.php +24 -0
  71. phpmailer/language/phpmailer.lang-hu.php +23 -0
  72. phpmailer/language/phpmailer.lang-it.php +28 -0
  73. phpmailer/language/phpmailer.lang-ja.php +25 -0
  74. phpmailer/language/phpmailer.lang-nl.php +23 -0
  75. phpmailer/language/phpmailer.lang-no.php +23 -0
  76. phpmailer/language/phpmailer.lang-pl.php +24 -0
  77. phpmailer/language/phpmailer.lang-ro.php +23 -0
  78. phpmailer/language/phpmailer.lang-ru.php +23 -0
  79. phpmailer/language/phpmailer.lang-se.php +24 -0
  80. phpmailer/language/phpmailer.lang-tr.php +25 -0
  81. readme.txt +30 -99
FirePHPCore/FirePHP.class.php ADDED
@@ -0,0 +1,1375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * *** BEGIN LICENSE BLOCK *****
4
+ *
5
+ * This file is part of FirePHP (http://www.firephp.org/).
6
+ *
7
+ * Software License Agreement (New BSD License)
8
+ *
9
+ * Copyright (c) 2006-2008, Christoph Dorn
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without modification,
13
+ * are permitted provided that the following conditions are met:
14
+ *
15
+ * * Redistributions of source code must retain the above copyright notice,
16
+ * this list of conditions and the following disclaimer.
17
+ *
18
+ * * Redistributions in binary form must reproduce the above copyright notice,
19
+ * this list of conditions and the following disclaimer in the documentation
20
+ * and/or other materials provided with the distribution.
21
+ *
22
+ * * Neither the name of Christoph Dorn nor the names of its
23
+ * contributors may be used to endorse or promote products derived from this
24
+ * software without specific prior written permission.
25
+ *
26
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ *
37
+ * ***** END LICENSE BLOCK *****
38
+ *
39
+ * @copyright Copyright (C) 2007-2008 Christoph Dorn
40
+ * @author Christoph Dorn <christoph@christophdorn.com>
41
+ * @license http://www.opensource.org/licenses/bsd-license.php
42
+ * @package FirePHP
43
+ */
44
+
45
+
46
+ /**
47
+ * Sends the given data to the FirePHP Firefox Extension.
48
+ * The data can be displayed in the Firebug Console or in the
49
+ * "Server" request tab.
50
+ *
51
+ * For more information see: http://www.firephp.org/
52
+ *
53
+ * @copyright Copyright (C) 2007-2008 Christoph Dorn
54
+ * @author Christoph Dorn <christoph@christophdorn.com>
55
+ * @license http://www.opensource.org/licenses/bsd-license.php
56
+ * @package FirePHP
57
+ */
58
+ class FirePHP {
59
+
60
+ /**
61
+ * FirePHP version
62
+ *
63
+ * @var string
64
+ */
65
+ const VERSION = '0.2.1';
66
+
67
+ /**
68
+ * Firebug LOG level
69
+ *
70
+ * Logs a message to firebug console.
71
+ *
72
+ * @var string
73
+ */
74
+ const LOG = 'LOG';
75
+
76
+ /**
77
+ * Firebug INFO level
78
+ *
79
+ * Logs a message to firebug console and displays an info icon before the message.
80
+ *
81
+ * @var string
82
+ */
83
+ const INFO = 'INFO';
84
+
85
+ /**
86
+ * Firebug WARN level
87
+ *
88
+ * Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise.
89
+ *
90
+ * @var string
91
+ */
92
+ const WARN = 'WARN';
93
+
94
+ /**
95
+ * Firebug ERROR level
96
+ *
97
+ * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count.
98
+ *
99
+ * @var string
100
+ */
101
+ const ERROR = 'ERROR';
102
+
103
+ /**
104
+ * Dumps a variable to firebug's server panel
105
+ *
106
+ * @var string
107
+ */
108
+ const DUMP = 'DUMP';
109
+
110
+ /**
111
+ * Displays a stack trace in firebug console
112
+ *
113
+ * @var string
114
+ */
115
+ const TRACE = 'TRACE';
116
+
117
+ /**
118
+ * Displays an exception in firebug console
119
+ *
120
+ * Increments the firebug error count.
121
+ *
122
+ * @var string
123
+ */
124
+ const EXCEPTION = 'EXCEPTION';
125
+
126
+ /**
127
+ * Displays an table in firebug console
128
+ *
129
+ * @var string
130
+ */
131
+ const TABLE = 'TABLE';
132
+
133
+ /**
134
+ * Starts a group in firebug console
135
+ *
136
+ * @var string
137
+ */
138
+ const GROUP_START = 'GROUP_START';
139
+
140
+ /**
141
+ * Ends a group in firebug console
142
+ *
143
+ * @var string
144
+ */
145
+ const GROUP_END = 'GROUP_END';
146
+
147
+ /**
148
+ * Singleton instance of FirePHP
149
+ *
150
+ * @var FirePHP
151
+ */
152
+ protected static $instance = null;
153
+
154
+ /**
155
+ * Wildfire protocol message index
156
+ *
157
+ * @var int
158
+ */
159
+ protected $messageIndex = 1;
160
+
161
+ /**
162
+ * Options for the library
163
+ *
164
+ * @var array
165
+ */
166
+ protected $options = array();
167
+
168
+ /**
169
+ * Filters used to exclude object members when encoding
170
+ *
171
+ * @var array
172
+ */
173
+ protected $objectFilters = array();
174
+
175
+ /**
176
+ * A stack of objects used to detect recursion during object encoding
177
+ *
178
+ * @var object
179
+ */
180
+ protected $objectStack = array();
181
+
182
+ /**
183
+ * Flag to enable/disable logging
184
+ *
185
+ * @var boolean
186
+ */
187
+ protected $enabled = true;
188
+
189
+ /**
190
+ * The object constructor
191
+ */
192
+ function __construct() {
193
+ $this->options['maxObjectDepth'] = 10;
194
+ $this->options['maxArrayDepth'] = 20;
195
+ $this->options['useNativeJsonEncode'] = true;
196
+ $this->options['includeLineNumbers'] = true;
197
+ }
198
+
199
+ /**
200
+ * When the object gets serialized only include specific object members.
201
+ *
202
+ * @return array
203
+ */
204
+ public function __sleep() {
205
+ return array('options','objectFilters','enabled');
206
+ }
207
+
208
+ /**
209
+ * Gets singleton instance of FirePHP
210
+ *
211
+ * @param boolean $AutoCreate
212
+ * @return FirePHP
213
+ */
214
+ public static function getInstance($AutoCreate=false) {
215
+ if($AutoCreate===true && !self::$instance) {
216
+ self::init();
217
+ }
218
+ return self::$instance;
219
+ }
220
+
221
+ /**
222
+ * Creates FirePHP object and stores it for singleton access
223
+ *
224
+ * @return FirePHP
225
+ */
226
+ public static function init() {
227
+ return self::$instance = new self();
228
+ }
229
+
230
+ /**
231
+ * Enable and disable logging to Firebug
232
+ *
233
+ * @param boolean $Enabled TRUE to enable, FALSE to disable
234
+ * @return void
235
+ */
236
+ public function setEnabled($Enabled) {
237
+ $this->enabled = $Enabled;
238
+ }
239
+
240
+ /**
241
+ * Check if logging is enabled
242
+ *
243
+ * @return boolean TRUE if enabled
244
+ */
245
+ public function getEnabled() {
246
+ return $this->enabled;
247
+ }
248
+
249
+ /**
250
+ * Specify a filter to be used when encoding an object
251
+ *
252
+ * Filters are used to exclude object members.
253
+ *
254
+ * @param string $Class The class name of the object
255
+ * @param array $Filter An array or members to exclude
256
+ * @return void
257
+ */
258
+ public function setObjectFilter($Class, $Filter) {
259
+ $this->objectFilters[$Class] = $Filter;
260
+ }
261
+
262
+ /**
263
+ * Set some options for the library
264
+ *
265
+ * Options:
266
+ * - maxObjectDepth: The maximum depth to traverse objects (default: 10)
267
+ * - maxArrayDepth: The maximum depth to traverse arrays (default: 20)
268
+ * - useNativeJsonEncode: If true will use json_encode() (default: true)
269
+ * - includeLineNumbers: If true will include line numbers and filenames (default: true)
270
+ *
271
+ * @param array $Options The options to be set
272
+ * @return void
273
+ */
274
+ public function setOptions($Options) {
275
+ $this->options = array_merge($this->options,$Options);
276
+ }
277
+
278
+ /**
279
+ * Register FirePHP as your error handler
280
+ *
281
+ * Will throw exceptions for each php error.
282
+ */
283
+ public function registerErrorHandler()
284
+ {
285
+ //NOTE: The following errors will not be caught by this error handler:
286
+ // E_ERROR, E_PARSE, E_CORE_ERROR,
287
+ // E_CORE_WARNING, E_COMPILE_ERROR,
288
+ // E_COMPILE_WARNING, E_STRICT
289
+
290
+ set_error_handler(array($this,'errorHandler'));
291
+ }
292
+
293
+ /**
294
+ * FirePHP's error handler
295
+ *
296
+ * Throws exception for each php error that will occur.
297
+ *
298
+ * @param int $errno
299
+ * @param string $errstr
300
+ * @param string $errfile
301
+ * @param int $errline
302
+ * @param array $errcontext
303
+ */
304
+ public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
305
+ {
306
+ // Don't throw exception if error reporting is switched off
307
+ if (error_reporting() == 0) {
308
+ return;
309
+ }
310
+ // Only throw exceptions for errors we are asking for
311
+ if (error_reporting() & $errno) {
312
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Register FirePHP as your exception handler
318
+ */
319
+ public function registerExceptionHandler()
320
+ {
321
+ set_exception_handler(array($this,'exceptionHandler'));
322
+ }
323
+
324
+ /**
325
+ * FirePHP's exception handler
326
+ *
327
+ * Logs all exceptions to your firebug console and then stops the script.
328
+ *
329
+ * @param Exception $Exception
330
+ * @throws Exception
331
+ */
332
+ function exceptionHandler($Exception) {
333
+ $this->fb($Exception);
334
+ }
335
+
336
+ /**
337
+ * Set custom processor url for FirePHP
338
+ *
339
+ * @param string $URL
340
+ */
341
+ public function setProcessorUrl($URL)
342
+ {
343
+ $this->setHeader('X-FirePHP-ProcessorURL', $URL);
344
+ }
345
+
346
+ /**
347
+ * Set custom renderer url for FirePHP
348
+ *
349
+ * @param string $URL
350
+ */
351
+ public function setRendererUrl($URL)
352
+ {
353
+ $this->setHeader('X-FirePHP-RendererURL', $URL);
354
+ }
355
+
356
+ /**
357
+ * Start a group for following messages
358
+ *
359
+ * @param string $Name
360
+ * @return true
361
+ * @throws Exception
362
+ */
363
+ public function group($Name) {
364
+ return $this->fb(null, $Name, FirePHP::GROUP_START);
365
+ }
366
+
367
+ /**
368
+ * Ends a group you have started before
369
+ *
370
+ * @return true
371
+ * @throws Exception
372
+ */
373
+ public function groupEnd() {
374
+ return $this->fb(null, null, FirePHP::GROUP_END);
375
+ }
376
+
377
+ /**
378
+ * Log object with label to firebug console
379
+ *
380
+ * @see FirePHP::LOG
381
+ * @param mixes $Object
382
+ * @param string $Label
383
+ * @return true
384
+ * @throws Exception
385
+ */
386
+ public function log($Object, $Label=null) {
387
+ return $this->fb($Object, $Label, FirePHP::LOG);
388
+ }
389
+
390
+ /**
391
+ * Log object with label to firebug console
392
+ *
393
+ * @see FirePHP::INFO
394
+ * @param mixes $Object
395
+ * @param string $Label
396
+ * @return true
397
+ * @throws Exception
398
+ */
399
+ public function info($Object, $Label=null) {
400
+ return $this->fb($Object, $Label, FirePHP::INFO);
401
+ }
402
+
403
+ /**
404
+ * Log object with label to firebug console
405
+ *
406
+ * @see FirePHP::WARN
407
+ * @param mixes $Object
408
+ * @param string $Label
409
+ * @return true
410
+ * @throws Exception
411
+ */
412
+ public function warn($Object, $Label=null) {
413
+ return $this->fb($Object, $Label, FirePHP::WARN);
414
+ }
415
+
416
+ /**
417
+ * Log object with label to firebug console
418
+ *
419
+ * @see FirePHP::ERROR
420
+ * @param mixes $Object
421
+ * @param string $Label
422
+ * @return true
423
+ * @throws Exception
424
+ */
425
+ public function error($Object, $Label=null) {
426
+ return $this->fb($Object, $Label, FirePHP::ERROR);
427
+ }
428
+
429
+ /**
430
+ * Dumps key and variable to firebug server panel
431
+ *
432
+ * @see FirePHP::DUMP
433
+ * @param string $Key
434
+ * @param mixed $Variable
435
+ * @return true
436
+ * @throws Exception
437
+ */
438
+ public function dump($Key, $Variable) {
439
+ return $this->fb($Variable, $Key, FirePHP::DUMP);
440
+ }
441
+
442
+ /**
443
+ * Log a trace in the firebug console
444
+ *
445
+ * @see FirePHP::TRACE
446
+ * @param string $Label
447
+ * @return true
448
+ * @throws Exception
449
+ */
450
+ public function trace($Label) {
451
+ return $this->fb($Label, FirePHP::TRACE);
452
+ }
453
+
454
+ /**
455
+ * Log a table in the firebug console
456
+ *
457
+ * @see FirePHP::TABLE
458
+ * @param string $Label
459
+ * @param string $Table
460
+ * @return true
461
+ * @throws Exception
462
+ */
463
+ public function table($Label, $Table) {
464
+ return $this->fb($Table, $Label, FirePHP::TABLE);
465
+ }
466
+
467
+ /**
468
+ * Check if FirePHP is installed on client
469
+ *
470
+ * @return boolean
471
+ */
472
+ public function detectClientExtension() {
473
+ /* Check if FirePHP is installed on client */
474
+ if(!@preg_match_all('/\sFirePHP\/([\.|\d]*)\s?/si',$this->getUserAgent(),$m) ||
475
+ !version_compare($m[1][0],'0.0.6','>=')) {
476
+ return false;
477
+ }
478
+ return true;
479
+ }
480
+
481
+ /**
482
+ * Log varible to Firebug
483
+ *
484
+ * @see http://www.firephp.org/Wiki/Reference/Fb
485
+ * @param mixed $Object The variable to be logged
486
+ * @return true Return TRUE if message was added to headers, FALSE otherwise
487
+ * @throws Exception
488
+ */
489
+ public function fb($Object) {
490
+
491
+ if(!$this->enabled) {
492
+ return false;
493
+ }
494
+
495
+ if (headers_sent($filename, $linenum)) {
496
+ throw $this->newException('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.');
497
+ }
498
+
499
+ $Type = null;
500
+ $Label = null;
501
+
502
+ if(func_num_args()==1) {
503
+ } else
504
+ if(func_num_args()==2) {
505
+ switch(func_get_arg(1)) {
506
+ case self::LOG:
507
+ case self::INFO:
508
+ case self::WARN:
509
+ case self::ERROR:
510
+ case self::DUMP:
511
+ case self::TRACE:
512
+ case self::EXCEPTION:
513
+ case self::TABLE:
514
+ case self::GROUP_START:
515
+ case self::GROUP_END:
516
+ $Type = func_get_arg(1);
517
+ break;
518
+ default:
519
+ $Label = func_get_arg(1);
520
+ break;
521
+ }
522
+ } else
523
+ if(func_num_args()==3) {
524
+ $Type = func_get_arg(2);
525
+ $Label = func_get_arg(1);
526
+ } else {
527
+ throw $this->newException('Wrong number of arguments to fb() function!');
528
+ }
529
+
530
+
531
+ if(!$this->detectClientExtension()) {
532
+ return false;
533
+ }
534
+
535
+ $meta = array();
536
+ $skipFinalObjectEncode = false;
537
+
538
+ if($Object instanceof Exception) {
539
+
540
+ $meta['file'] = $this->_escapeTraceFile($Object->getFile());
541
+ $meta['line'] = $Object->getLine();
542
+
543
+ $trace = $Object->getTrace();
544
+ if($Object instanceof ErrorException
545
+ && isset($trace[0]['function'])
546
+ && $trace[0]['function']=='errorHandler'
547
+ && isset($trace[0]['class'])
548
+ && $trace[0]['class']=='FirePHP') {
549
+
550
+ $severity = false;
551
+ switch($Object->getSeverity()) {
552
+ case E_WARNING: $severity = 'E_WARNING'; break;
553
+ case E_NOTICE: $severity = 'E_NOTICE'; break;
554
+ case E_USER_ERROR: $severity = 'E_USER_ERROR'; break;
555
+ case E_USER_WARNING: $severity = 'E_USER_WARNING'; break;
556
+ case E_USER_NOTICE: $severity = 'E_USER_NOTICE'; break;
557
+ case E_STRICT: $severity = 'E_STRICT'; break;
558
+ case E_RECOVERABLE_ERROR: $severity = 'E_RECOVERABLE_ERROR'; break;
559
+ case E_DEPRECATED: $severity = 'E_DEPRECATED'; break;
560
+ case E_USER_DEPRECATED: $severity = 'E_USER_DEPRECATED'; break;
561
+ }
562
+
563
+ $Object = array('Class'=>get_class($Object),
564
+ 'Message'=>$severity.': '.$Object->getMessage(),
565
+ 'File'=>$this->_escapeTraceFile($Object->getFile()),
566
+ 'Line'=>$Object->getLine(),
567
+ 'Type'=>'trigger',
568
+ 'Trace'=>$this->_escapeTrace(array_splice($trace,2)));
569
+ $skipFinalObjectEncode = true;
570
+ } else {
571
+ $Object = array('Class'=>get_class($Object),
572
+ 'Message'=>$Object->getMessage(),
573
+ 'File'=>$this->_escapeTraceFile($Object->getFile()),
574
+ 'Line'=>$Object->getLine(),
575
+ 'Type'=>'throw',
576
+ 'Trace'=>$this->_escapeTrace($trace));
577
+ $skipFinalObjectEncode = true;
578
+ }
579
+ $Type = self::EXCEPTION;
580
+
581
+ } else
582
+ if($Type==self::TRACE) {
583
+
584
+ $trace = debug_backtrace();
585
+ if(!$trace) return false;
586
+ for( $i=0 ; $i<sizeof($trace) ; $i++ ) {
587
+
588
+ if(isset($trace[$i]['class'])
589
+ && isset($trace[$i]['file'])
590
+ && ($trace[$i]['class']=='FirePHP'
591
+ || $trace[$i]['class']=='FB')
592
+ && (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php'
593
+ || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) {
594
+ /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
595
+ } else
596
+ if(isset($trace[$i]['class'])
597
+ && isset($trace[$i+1]['file'])
598
+ && $trace[$i]['class']=='FirePHP'
599
+ && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') {
600
+ /* Skip fb() */
601
+ } else
602
+ if($trace[$i]['function']=='fb'
603
+ || $trace[$i]['function']=='trace'
604
+ || $trace[$i]['function']=='send') {
605
+ $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'',
606
+ 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'',
607
+ 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'',
608
+ 'Message'=>$trace[$i]['args'][0],
609
+ 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'',
610
+ 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'',
611
+ 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'',
612
+ 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1)));
613
+
614
+ $skipFinalObjectEncode = true;
615
+ $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'';
616
+ $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:'';
617
+ break;
618
+ }
619
+ }
620
+
621
+ } else
622
+ if($Type==self::TABLE) {
623
+
624
+ if(isset($Object[0]) && is_string($Object[0])) {
625
+ $Object[1] = $this->encodeTable($Object[1]);
626
+ } else {
627
+ $Object = $this->encodeTable($Object);
628
+ }
629
+
630
+ $skipFinalObjectEncode = true;
631
+
632
+ } else {
633
+ if($Type===null) {
634
+ $Type = self::LOG;
635
+ }
636
+ }
637
+
638
+ if($this->options['includeLineNumbers']) {
639
+ if(!isset($meta['file']) || !isset($meta['line'])) {
640
+
641
+ $trace = debug_backtrace();
642
+ for( $i=0 ; $trace && $i<sizeof($trace) ; $i++ ) {
643
+
644
+ if(isset($trace[$i]['class'])
645
+ && isset($trace[$i]['file'])
646
+ && ($trace[$i]['class']=='FirePHP'
647
+ || $trace[$i]['class']=='FB')
648
+ && (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php'
649
+ || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) {
650
+ /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
651
+ } else
652
+ if(isset($trace[$i]['class'])
653
+ && isset($trace[$i+1]['file'])
654
+ && $trace[$i]['class']=='FirePHP'
655
+ && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') {
656
+ /* Skip fb() */
657
+ } else
658
+ if(isset($trace[$i]['file'])
659
+ && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') {
660
+ /* Skip FB::fb() */
661
+ } else {
662
+ $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'';
663
+ $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:'';
664
+ break;
665
+ }
666
+ }
667
+
668
+ }
669
+ } else {
670
+ unset($meta['file']);
671
+ unset($meta['line']);
672
+ }
673
+
674
+ $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
675
+ $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.self::VERSION);
676
+
677
+ $structure_index = 1;
678
+ if($Type==self::DUMP) {
679
+ $structure_index = 2;
680
+ $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
681
+ } else {
682
+ $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
683
+ }
684
+
685
+ if($Type==self::DUMP) {
686
+ $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}';
687
+ } else {
688
+ $msg_meta = array('Type'=>$Type);
689
+ if($Label!==null) {
690
+ $msg_meta['Label'] = $Label;
691
+ }
692
+ if(isset($meta['file'])) {
693
+ $msg_meta['File'] = $meta['file'];
694
+ }
695
+ if(isset($meta['line'])) {
696
+ $msg_meta['Line'] = $meta['line'];
697
+ }
698
+ $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']';
699
+ }
700
+
701
+ $parts = explode("\n",chunk_split($msg, 5000, "\n"));
702
+
703
+ for( $i=0 ; $i<count($parts) ; $i++) {
704
+
705
+ $part = $parts[$i];
706
+ if ($part) {
707
+
708
+ if(count($parts)>2) {
709
+ // Message needs to be split into multiple parts
710
+ $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex,
711
+ (($i==0)?strlen($msg):'')
712
+ . '|' . $part . '|'
713
+ . (($i<count($parts)-2)?'\\':''));
714
+ } else {
715
+ $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex,
716
+ strlen($part) . '|' . $part . '|');
717
+ }
718
+
719
+ $this->messageIndex++;
720
+
721
+ if ($this->messageIndex > 99999) {
722
+ throw new Exception('Maximum number (99,999) of messages reached!');
723
+ }
724
+ }
725
+ }
726
+
727
+ $this->setHeader('X-Wf-1-Index',$this->messageIndex-1);
728
+
729
+ return true;
730
+ }
731
+
732
+ /**
733
+ * Standardizes path for windows systems.
734
+ *
735
+ * @param string $Path
736
+ * @return string
737
+ */
738
+ protected function _standardizePath($Path) {
739
+ return preg_replace('/\\\\+/','/',$Path);
740
+ }
741
+
742
+ /**
743
+ * Escape trace path for windows systems
744
+ *
745
+ * @param array $Trace
746
+ * @return array
747
+ */
748
+ protected function _escapeTrace($Trace) {
749
+ if(!$Trace) return $Trace;
750
+ for( $i=0 ; $i<sizeof($Trace) ; $i++ ) {
751
+ if(isset($Trace[$i]['file'])) {
752
+ $Trace[$i]['file'] = $this->_escapeTraceFile($Trace[$i]['file']);
753
+ }
754
+ if(isset($Trace[$i]['args'])) {
755
+ $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']);
756
+ }
757
+ }
758
+ return $Trace;
759
+ }
760
+
761
+ /**
762
+ * Escape file information of trace for windows systems
763
+ *
764
+ * @param string $File
765
+ * @return string
766
+ */
767
+ protected function _escapeTraceFile($File) {
768
+ /* Check if we have a windows filepath */
769
+ if(strpos($File,'\\')) {
770
+ /* First strip down to single \ */
771
+
772
+ $file = preg_replace('/\\\\+/','\\',$File);
773
+
774
+ return $file;
775
+ }
776
+ return $File;
777
+ }
778
+
779
+ /**
780
+ * Send header
781
+ *
782
+ * @param string $Name
783
+ * @param string_type $Value
784
+ */
785
+ protected function setHeader($Name, $Value) {
786
+ return header($Name.': '.$Value);
787
+ }
788
+
789
+ /**
790
+ * Get user agent
791
+ *
792
+ * @return string|false
793
+ */
794
+ protected function getUserAgent() {
795
+ if(!isset($_SERVER['HTTP_USER_AGENT'])) return false;
796
+ return $_SERVER['HTTP_USER_AGENT'];
797
+ }
798
+
799
+ /**
800
+ * Returns a new exception
801
+ *
802
+ * @param string $Message
803
+ * @return Exception
804
+ */
805
+ protected function newException($Message) {
806
+ return new Exception($Message);
807
+ }
808
+
809
+ /**
810
+ * Encode an object into a JSON string
811
+ *
812
+ * Uses PHP's jeson_encode() if available
813
+ *
814
+ * @param object $Object The object to be encoded
815
+ * @return string The JSON string
816
+ */
817
+ public function jsonEncode($Object, $skipObjectEncode=false)
818
+ {
819
+ if(!$skipObjectEncode) {
820
+ $Object = $this->encodeObject($Object);
821
+ }
822
+
823
+ if(function_exists('json_encode')
824
+ && $this->options['useNativeJsonEncode']!=false) {
825
+
826
+ return json_encode($Object);
827
+ } else {
828
+ return $this->json_encode($Object);
829
+ }
830
+ }
831
+
832
+ /**
833
+ * Encodes a table by encoding each row and column with encodeObject()
834
+ *
835
+ * @param array $Table The table to be encoded
836
+ * @return array
837
+ */
838
+ protected function encodeTable($Table) {
839
+ if(!$Table) return $Table;
840
+ for( $i=0 ; $i<count($Table) ; $i++ ) {
841
+ if(is_array($Table[$i])) {
842
+ for( $j=0 ; $j<count($Table[$i]) ; $j++ ) {
843
+ $Table[$i][$j] = $this->encodeObject($Table[$i][$j]);
844
+ }
845
+ }
846
+ }
847
+ return $Table;
848
+ }
849
+
850
+ /**
851
+ * Encodes an object including members with
852
+ * protected and private visibility
853
+ *
854
+ * @param Object $Object The object to be encoded
855
+ * @param int $Depth The current traversal depth
856
+ * @return array All members of the object
857
+ */
858
+ protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1)
859
+ {
860
+ $return = array();
861
+
862
+ if (is_resource($Object)) {
863
+
864
+ return '** '.(string)$Object.' **';
865
+
866
+ } else
867
+ if (is_object($Object)) {
868
+
869
+ if ($ObjectDepth > $this->options['maxObjectDepth']) {
870
+ return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **';
871
+ }
872
+
873
+ foreach ($this->objectStack as $refVal) {
874
+ if ($refVal === $Object) {
875
+ return '** Recursion ('.get_class($Object).') **';
876
+ }
877
+ }
878
+ array_push($this->objectStack, $Object);
879
+
880
+ $return['__className'] = $class = get_class($Object);
881
+
882
+ $reflectionClass = new ReflectionClass($class);
883
+ $properties = array();
884
+ foreach( $reflectionClass->getProperties() as $property) {
885
+ $properties[$property->getName()] = $property;
886
+ }
887
+
888
+ $members = (array)$Object;
889
+
890
+ foreach( $properties as $raw_name => $property ) {
891
+
892
+ $name = $raw_name;
893
+ if($property->isStatic()) {
894
+ $name = 'static:'.$name;
895
+ }
896
+ if($property->isPublic()) {
897
+ $name = 'public:'.$name;
898
+ } else
899
+ if($property->isPrivate()) {
900
+ $name = 'private:'.$name;
901
+ $raw_name = "\0".$class."\0".$raw_name;
902
+ } else
903
+ if($property->isProtected()) {
904
+ $name = 'protected:'.$name;
905
+ $raw_name = "\0".'*'."\0".$raw_name;
906
+ }
907
+
908
+ if(!(isset($this->objectFilters[$class])
909
+ && is_array($this->objectFilters[$class])
910
+ && in_array($raw_name,$this->objectFilters[$class]))) {
911
+
912
+ if(array_key_exists($raw_name,$members)
913
+ && !$property->isStatic()) {
914
+
915
+ $return[$name] = $this->encodeObject($members[$raw_name], $ObjectDepth + 1, 1);
916
+
917
+ } else {
918
+ if(method_exists($property,'setAccessible')) {
919
+ $property->setAccessible(true);
920
+ $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1);
921
+ } else
922
+ if($property->isPublic()) {
923
+ $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1);
924
+ } else {
925
+ $return[$name] = '** Need PHP 5.3 to get value **';
926
+ }
927
+ }
928
+ } else {
929
+ $return[$name] = '** Excluded by Filter **';
930
+ }
931
+ }
932
+
933
+ // Include all members that are not defined in the class
934
+ // but exist in the object
935
+ foreach( $members as $raw_name => $value ) {
936
+
937
+ $name = $raw_name;
938
+
939
+ if ($name{0} == "\0") {
940
+ $parts = explode("\0", $name);
941
+ $name = $parts[2];
942
+ }
943
+
944
+ if(!isset($properties[$name])) {
945
+ $name = 'undeclared:'.$name;
946
+
947
+ if(!(isset($this->objectFilters[$class])
948
+ && is_array($this->objectFilters[$class])
949
+ && in_array($raw_name,$this->objectFilters[$class]))) {
950
+
951
+ $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1);
952
+ } else {
953
+ $return[$name] = '** Excluded by Filter **';
954
+ }
955
+ }
956
+ }
957
+
958
+ array_pop($this->objectStack);
959
+
960
+ } elseif (is_array($Object)) {
961
+
962
+ if ($ArrayDepth > $this->options['maxArrayDepth']) {
963
+ return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **';
964
+ }
965
+
966
+ foreach ($Object as $key => $val) {
967
+
968
+ // Encoding the $GLOBALS PHP array causes an infinite loop
969
+ // if the recursion is not reset here as it contains
970
+ // a reference to itself. This is the only way I have come up
971
+ // with to stop infinite recursion in this case.
972
+ if($key=='GLOBALS'
973
+ && is_array($val)
974
+ && array_key_exists('GLOBALS',$val)) {
975
+ $val['GLOBALS'] = '** Recursion (GLOBALS) **';
976
+ }
977
+
978
+ $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1);
979
+ }
980
+ } else {
981
+ if(self::is_utf8($Object)) {
982
+ return $Object;
983
+ } else {
984
+ return utf8_encode($Object);
985
+ }
986
+ }
987
+ return $return;
988
+ }
989
+
990
+ /**
991
+ * Returns true if $string is valid UTF-8 and false otherwise.
992
+ *
993
+ * @param mixed $str String to be tested
994
+ * @return boolean
995
+ */
996
+ protected static function is_utf8($str) {
997
+ $c=0; $b=0;
998
+ $bits=0;
999
+ $len=strlen($str);
1000
+ for($i=0; $i<$len; $i++){
1001
+ $c=ord($str[$i]);
1002
+ if($c > 128){
1003
+ if(($c >= 254)) return false;
1004
+ elseif($c >= 252) $bits=6;
1005
+ elseif($c >= 248) $bits=5;
1006
+ elseif($c >= 240) $bits=4;
1007
+ elseif($c >= 224) $bits=3;
1008
+ elseif($c >= 192) $bits=2;
1009
+ else return false;
1010
+ if(($i+$bits) > $len) return false;
1011
+ while($bits > 1){
1012
+ $i++;
1013
+ $b=ord($str[$i]);
1014
+ if($b < 128 || $b > 191) return false;
1015
+ $bits--;
1016
+ }
1017
+ }
1018
+ }
1019
+ return true;
1020
+ }
1021
+
1022
+ /**
1023
+ * Converts to and from JSON format.
1024
+ *
1025
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
1026
+ * format. It is easy for humans to read and write. It is easy for machines
1027
+ * to parse and generate. It is based on a subset of the JavaScript
1028
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
1029
+ * This feature can also be found in Python. JSON is a text format that is
1030
+ * completely language independent but uses conventions that are familiar
1031
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
1032
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
1033
+ * ideal data-interchange language.
1034
+ *
1035
+ * This package provides a simple encoder and decoder for JSON notation. It
1036
+ * is intended for use with client-side Javascript applications that make
1037
+ * use of HTTPRequest to perform server communication functions - data can
1038
+ * be encoded into JSON notation for use in a client-side javascript, or
1039
+ * decoded from incoming Javascript requests. JSON format is native to
1040
+ * Javascript, and can be directly eval()'ed with no further parsing
1041
+ * overhead
1042
+ *
1043
+ * All strings should be in ASCII or UTF-8 format!
1044
+ *
1045
+ * LICENSE: Redistribution and use in source and binary forms, with or
1046
+ * without modification, are permitted provided that the following
1047
+ * conditions are met: Redistributions of source code must retain the
1048
+ * above copyright notice, this list of conditions and the following
1049
+ * disclaimer. Redistributions in binary form must reproduce the above
1050
+ * copyright notice, this list of conditions and the following disclaimer
1051
+ * in the documentation and/or other materials provided with the
1052
+ * distribution.
1053
+ *
1054
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1055
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1056
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1057
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
1058
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1059
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
1060
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1061
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1062
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1063
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1064
+ * DAMAGE.
1065
+ *
1066
+ * @category
1067
+ * @package Services_JSON
1068
+ * @author Michal Migurski <mike-json@teczno.com>
1069
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
1070
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
1071
+ * @author Christoph Dorn <christoph@christophdorn.com>
1072
+ * @copyright 2005 Michal Migurski
1073
+ * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
1074
+ * @license http://www.opensource.org/licenses/bsd-license.php
1075
+ * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
1076
+ */
1077
+
1078
+
1079
+ /**
1080
+ * Keep a list of objects as we descend into the array so we can detect recursion.
1081
+ */
1082
+ private $json_objectStack = array();
1083
+
1084
+
1085
+ /**
1086
+ * convert a string from one UTF-8 char to one UTF-16 char
1087
+ *
1088
+ * Normally should be handled by mb_convert_encoding, but
1089
+ * provides a slower PHP-only method for installations
1090
+ * that lack the multibye string extension.
1091
+ *
1092
+ * @param string $utf8 UTF-8 character
1093
+ * @return string UTF-16 character
1094
+ * @access private
1095
+ */
1096
+ private function json_utf82utf16($utf8)
1097
+ {
1098
+ // oh please oh please oh please oh please oh please
1099
+ if(function_exists('mb_convert_encoding')) {
1100
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
1101
+ }
1102
+
1103
+ switch(strlen($utf8)) {
1104
+ case 1:
1105
+ // this case should never be reached, because we are in ASCII range
1106
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1107
+ return $utf8;
1108
+
1109
+ case 2:
1110
+ // return a UTF-16 character from a 2-byte UTF-8 char
1111
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1112
+ return chr(0x07 & (ord($utf8{0}) >> 2))
1113
+ . chr((0xC0 & (ord($utf8{0}) << 6))
1114
+ | (0x3F & ord($utf8{1})));
1115
+
1116
+ case 3:
1117
+ // return a UTF-16 character from a 3-byte UTF-8 char
1118
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1119
+ return chr((0xF0 & (ord($utf8{0}) << 4))
1120
+ | (0x0F & (ord($utf8{1}) >> 2)))
1121
+ . chr((0xC0 & (ord($utf8{1}) << 6))
1122
+ | (0x7F & ord($utf8{2})));
1123
+ }
1124
+
1125
+ // ignoring UTF-32 for now, sorry
1126
+ return '';
1127
+ }
1128
+
1129
+ /**
1130
+ * encodes an arbitrary variable into JSON format
1131
+ *
1132
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
1133
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
1134
+ * if var is a strng, note that encode() always expects it
1135
+ * to be in ASCII or UTF-8 format!
1136
+ *
1137
+ * @return mixed JSON string representation of input var or an error if a problem occurs
1138
+ * @access public
1139
+ */
1140
+ private function json_encode($var)
1141
+ {
1142
+
1143
+ if(is_object($var)) {
1144
+ if(in_array($var,$this->json_objectStack)) {
1145
+ return '"** Recursion **"';
1146
+ }
1147
+ }
1148
+
1149
+ switch (gettype($var)) {
1150
+ case 'boolean':
1151
+ return $var ? 'true' : 'false';
1152
+
1153
+ case 'NULL':
1154
+ return 'null';
1155
+
1156
+ case 'integer':
1157
+ return (int) $var;
1158
+
1159
+ case 'double':
1160
+ case 'float':
1161
+ return (float) $var;
1162
+
1163
+ case 'string':
1164
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
1165
+ $ascii = '';
1166
+ $strlen_var = strlen($var);
1167
+
1168
+ /*
1169
+ * Iterate over every character in the string,
1170
+ * escaping with a slash or encoding to UTF-8 where necessary
1171
+ */
1172
+ for ($c = 0; $c < $strlen_var; ++$c) {
1173
+
1174
+ $ord_var_c = ord($var{$c});
1175
+
1176
+ switch (true) {
1177
+ case $ord_var_c == 0x08:
1178
+ $ascii .= '\b';
1179
+ break;
1180
+ case $ord_var_c == 0x09:
1181
+ $ascii .= '\t';
1182
+ break;
1183
+ case $ord_var_c == 0x0A:
1184
+ $ascii .= '\n';
1185
+ break;
1186
+ case $ord_var_c == 0x0C:
1187
+ $ascii .= '\f';
1188
+ break;
1189
+ case $ord_var_c == 0x0D:
1190
+ $ascii .= '\r';
1191
+ break;
1192
+
1193
+ case $ord_var_c == 0x22:
1194
+ case $ord_var_c == 0x2F:
1195
+ case $ord_var_c == 0x5C:
1196
+ // double quote, slash, slosh
1197
+ $ascii .= '\\'.$var{$c};
1198
+ break;
1199
+
1200
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
1201
+ // characters U-00000000 - U-0000007F (same as ASCII)
1202
+ $ascii .= $var{$c};
1203
+ break;
1204
+
1205
+ case (($ord_var_c & 0xE0) == 0xC0):
1206
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
1207
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1208
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
1209
+ $c += 1;
1210
+ $utf16 = $this->json_utf82utf16($char);
1211
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1212
+ break;
1213
+
1214
+ case (($ord_var_c & 0xF0) == 0xE0):
1215
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
1216
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1217
+ $char = pack('C*', $ord_var_c,
1218
+ ord($var{$c + 1}),
1219
+ ord($var{$c + 2}));
1220
+ $c += 2;
1221
+ $utf16 = $this->json_utf82utf16($char);
1222
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1223
+ break;
1224
+
1225
+ case (($ord_var_c & 0xF8) == 0xF0):
1226
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
1227
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1228
+ $char = pack('C*', $ord_var_c,
1229
+ ord($var{$c + 1}),
1230
+ ord($var{$c + 2}),
1231
+ ord($var{$c + 3}));
1232
+ $c += 3;
1233
+ $utf16 = $this->json_utf82utf16($char);
1234
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1235
+ break;
1236
+
1237
+ case (($ord_var_c & 0xFC) == 0xF8):
1238
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
1239
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1240
+ $char = pack('C*', $ord_var_c,
1241
+ ord($var{$c + 1}),
1242
+ ord($var{$c + 2}),
1243
+ ord($var{$c + 3}),
1244
+ ord($var{$c + 4}));
1245
+ $c += 4;
1246
+ $utf16 = $this->json_utf82utf16($char);
1247
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1248
+ break;
1249
+
1250
+ case (($ord_var_c & 0xFE) == 0xFC):
1251
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
1252
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1253
+ $char = pack('C*', $ord_var_c,
1254
+ ord($var{$c + 1}),
1255
+ ord($var{$c + 2}),
1256
+ ord($var{$c + 3}),
1257
+ ord($var{$c + 4}),
1258
+ ord($var{$c + 5}));
1259
+ $c += 5;
1260
+ $utf16 = $this->json_utf82utf16($char);
1261
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1262
+ break;
1263
+ }
1264
+ }
1265
+
1266
+ return '"'.$ascii.'"';
1267
+
1268
+ case 'array':
1269
+ /*
1270
+ * As per JSON spec if any array key is not an integer
1271
+ * we must treat the the whole array as an object. We
1272
+ * also try to catch a sparsely populated associative
1273
+ * array with numeric keys here because some JS engines
1274
+ * will create an array with empty indexes up to
1275
+ * max_index which can cause memory issues and because
1276
+ * the keys, which may be relevant, will be remapped
1277
+ * otherwise.
1278
+ *
1279
+ * As per the ECMA and JSON specification an object may
1280
+ * have any string as a property. Unfortunately due to
1281
+ * a hole in the ECMA specification if the key is a
1282
+ * ECMA reserved word or starts with a digit the
1283
+ * parameter is only accessible using ECMAScript's
1284
+ * bracket notation.
1285
+ */
1286
+
1287
+ // treat as a JSON object
1288
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
1289
+
1290
+ $this->json_objectStack[] = $var;
1291
+
1292
+ $properties = array_map(array($this, 'json_name_value'),
1293
+ array_keys($var),
1294
+ array_values($var));
1295
+
1296
+ array_pop($this->json_objectStack);
1297
+
1298
+ foreach($properties as $property) {
1299
+ if($property instanceof Exception) {
1300
+ return $property;
1301
+ }
1302
+ }
1303
+
1304
+ return '{' . join(',', $properties) . '}';
1305
+ }
1306
+
1307
+ $this->json_objectStack[] = $var;
1308
+
1309
+ // treat it like a regular array
1310
+ $elements = array_map(array($this, 'json_encode'), $var);
1311
+
1312
+ array_pop($this->json_objectStack);
1313
+
1314
+ foreach($elements as $element) {
1315
+ if($element instanceof Exception) {
1316
+ return $element;
1317
+ }
1318
+ }
1319
+
1320
+ return '[' . join(',', $elements) . ']';
1321
+
1322
+ case 'object':
1323
+ $vars = self::encodeObject($var);
1324
+
1325
+ $this->json_objectStack[] = $var;
1326
+
1327
+ $properties = array_map(array($this, 'json_name_value'),
1328
+ array_keys($vars),
1329
+ array_values($vars));
1330
+
1331
+ array_pop($this->json_objectStack);
1332
+
1333
+ foreach($properties as $property) {
1334
+ if($property instanceof Exception) {
1335
+ return $property;
1336
+ }
1337
+ }
1338
+
1339
+ return '{' . join(',', $properties) . '}';
1340
+
1341
+ default:
1342
+ return null;
1343
+ }
1344
+ }
1345
+
1346
+ /**
1347
+ * array-walking function for use in generating JSON-formatted name-value pairs
1348
+ *
1349
+ * @param string $name name of key to use
1350
+ * @param mixed $value reference to an array element to be encoded
1351
+ *
1352
+ * @return string JSON-formatted name-value pair, like '"name":value'
1353
+ * @access private
1354
+ */
1355
+ private function json_name_value($name, $value)
1356
+ {
1357
+ // Encoding the $GLOBALS PHP array causes an infinite loop
1358
+ // if the recursion is not reset here as it contains
1359
+ // a reference to itself. This is the only way I have come up
1360
+ // with to stop infinite recursion in this case.
1361
+ if($name=='GLOBALS'
1362
+ && is_array($value)
1363
+ && array_key_exists('GLOBALS',$value)) {
1364
+ $value['GLOBALS'] = '** Recursion **';
1365
+ }
1366
+
1367
+ $encoded_value = $this->json_encode($value);
1368
+
1369
+ if($encoded_value instanceof Exception) {
1370
+ return $encoded_value;
1371
+ }
1372
+
1373
+ return $this->json_encode(strval($name)) . ':' . $encoded_value;
1374
+ }
1375
+ }
FirePHPCore/LICENSE ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Software License Agreement (New BSD License)
2
+
3
+ Copyright (c) 2006-2008, Christoph Dorn
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification,
7
+ are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice,
10
+ this list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of Christoph Dorn nor the names of its
17
+ contributors may be used to endorse or promote products derived from this
18
+ software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FirePHPCore/fb.php ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* ***** BEGIN LICENSE BLOCK *****
4
+ *
5
+ * This file is part of FirePHP (http://www.firephp.org/).
6
+ *
7
+ * Software License Agreement (New BSD License)
8
+ *
9
+ * Copyright (c) 2006-2008, Christoph Dorn
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without modification,
13
+ * are permitted provided that the following conditions are met:
14
+ *
15
+ * * Redistributions of source code must retain the above copyright notice,
16
+ * this list of conditions and the following disclaimer.
17
+ *
18
+ * * Redistributions in binary form must reproduce the above copyright notice,
19
+ * this list of conditions and the following disclaimer in the documentation
20
+ * and/or other materials provided with the distribution.
21
+ *
22
+ * * Neither the name of Christoph Dorn nor the names of its
23
+ * contributors may be used to endorse or promote products derived from this
24
+ * software without specific prior written permission.
25
+ *
26
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ *
37
+ * ***** END LICENSE BLOCK *****
38
+ *
39
+ * @copyright Copyright (C) 2007-2008 Christoph Dorn
40
+ * @author Christoph Dorn <christoph@christophdorn.com>
41
+ * @license http://www.opensource.org/licenses/bsd-license.php
42
+ * @package FirePHP
43
+ */
44
+
45
+ require_once dirname(__FILE__).'/FirePHP.class.php';
46
+
47
+ /**
48
+ * Sends the given data to the FirePHP Firefox Extension.
49
+ * The data can be displayed in the Firebug Console or in the
50
+ * "Server" request tab.
51
+ *
52
+ * @see http://www.firephp.org/Wiki/Reference/Fb
53
+ * @param mixed $Object
54
+ * @return true
55
+ * @throws Exception
56
+ */
57
+ function fb()
58
+ {
59
+ $instance = FirePHP::getInstance(true);
60
+
61
+ $args = func_get_args();
62
+ return call_user_func_array(array($instance,'fb'),$args);
63
+ }
64
+
65
+
66
+ class FB
67
+ {
68
+ /**
69
+ * Enable and disable logging to Firebug
70
+ *
71
+ * @see FirePHP->setEnabled()
72
+ * @param boolean $Enabled TRUE to enable, FALSE to disable
73
+ * @return void
74
+ */
75
+ public static function setEnabled($Enabled) {
76
+ $instance = FirePHP::getInstance(true);
77
+ $instance->setEnabled($Enabled);
78
+ }
79
+
80
+ /**
81
+ * Check if logging is enabled
82
+ *
83
+ * @see FirePHP->getEnabled()
84
+ * @return boolean TRUE if enabled
85
+ */
86
+ public static function getEnabled() {
87
+ $instance = FirePHP::getInstance(true);
88
+ return $instance->getEnabled();
89
+ }
90
+
91
+ /**
92
+ * Specify a filter to be used when encoding an object
93
+ *
94
+ * Filters are used to exclude object members.
95
+ *
96
+ * @see FirePHP->setObjectFilter()
97
+ * @param string $Class The class name of the object
98
+ * @param array $Filter An array or members to exclude
99
+ * @return void
100
+ */
101
+ public static function setObjectFilter($Class, $Filter) {
102
+ $instance = FirePHP::getInstance(true);
103
+ $instance->setObjectFilter($Class, $Filter);
104
+ }
105
+
106
+ /**
107
+ * Set some options for the library
108
+ *
109
+ * @see FirePHP->setOptions()
110
+ * @param array $Options The options to be set
111
+ * @return void
112
+ */
113
+ public static function setOptions($Options) {
114
+ $instance = FirePHP::getInstance(true);
115
+ $instance->setOptions($Options);
116
+ }
117
+
118
+ /**
119
+ * Log object to firebug
120
+ *
121
+ * @see http://www.firephp.org/Wiki/Reference/Fb
122
+ * @param mixed $Object
123
+ * @return true
124
+ * @throws Exception
125
+ */
126
+ public static function send()
127
+ {
128
+ $instance = FirePHP::getInstance(true);
129
+ $args = func_get_args();
130
+ return call_user_func_array(array($instance,'fb'),$args);
131
+ }
132
+
133
+ /**
134
+ * Start a group for following messages
135
+ *
136
+ * @param string $Name
137
+ * @return true
138
+ * @throws Exception
139
+ */
140
+ public static function group($Name) {
141
+ return self::send(null, $Name, FirePHP::GROUP_START);
142
+ }
143
+
144
+ /**
145
+ * Ends a group you have started before
146
+ *
147
+ * @return true
148
+ * @throws Exception
149
+ */
150
+ public static function groupEnd() {
151
+ return self::send(null, null, FirePHP::GROUP_END);
152
+ }
153
+
154
+ /**
155
+ * Log object with label to firebug console
156
+ *
157
+ * @see FirePHP::LOG
158
+ * @param mixes $Object
159
+ * @param string $Label
160
+ * @return true
161
+ * @throws Exception
162
+ */
163
+ public static function log($Object, $Label=null) {
164
+ return self::send($Object, $Label, FirePHP::LOG);
165
+ }
166
+
167
+ /**
168
+ * Log object with label to firebug console
169
+ *
170
+ * @see FirePHP::INFO
171
+ * @param mixes $Object
172
+ * @param string $Label
173
+ * @return true
174
+ * @throws Exception
175
+ */
176
+ public static function info($Object, $Label=null) {
177
+ return self::send($Object, $Label, FirePHP::INFO);
178
+ }
179
+
180
+ /**
181
+ * Log object with label to firebug console
182
+ *
183
+ * @see FirePHP::WARN
184
+ * @param mixes $Object
185
+ * @param string $Label
186
+ * @return true
187
+ * @throws Exception
188
+ */
189
+ public static function warn($Object, $Label=null) {
190
+ return self::send($Object, $Label, FirePHP::WARN);
191
+ }
192
+
193
+ /**
194
+ * Log object with label to firebug console
195
+ *
196
+ * @see FirePHP::ERROR
197
+ * @param mixes $Object
198
+ * @param string $Label
199
+ * @return true
200
+ * @throws Exception
201
+ */
202
+ public static function error($Object, $Label=null) {
203
+ return self::send($Object, $Label, FirePHP::ERROR);
204
+ }
205
+
206
+ /**
207
+ * Dumps key and variable to firebug server panel
208
+ *
209
+ * @see FirePHP::DUMP
210
+ * @param string $Key
211
+ * @param mixed $Variable
212
+ * @return true
213
+ * @throws Exception
214
+ */
215
+ public static function dump($Key, $Variable) {
216
+ return self::send($Variable, $Key, FirePHP::DUMP);
217
+ }
218
+
219
+ /**
220
+ * Log a trace in the firebug console
221
+ *
222
+ * @see FirePHP::TRACE
223
+ * @param string $Label
224
+ * @return true
225
+ * @throws Exception
226
+ */
227
+ public static function trace($Label) {
228
+ return self::send($Label, FirePHP::TRACE);
229
+ }
230
+
231
+ /**
232
+ * Log a table in the firebug console
233
+ *
234
+ * @see FirePHP::TABLE
235
+ * @param string $Label
236
+ * @param string $Table
237
+ * @return true
238
+ * @throws Exception
239
+ */
240
+ public static function table($Label, $Table) {
241
+ return self::send($Table, $Label, FirePHP::TABLE);
242
+ }
243
+
244
+ }
245
+
246
+
dbem-recurrence.php ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+ function dbem_recurrence_test() {
6
+ echo "<h2>Recurrence iCalendar</h2>";
7
+
8
+ echo "<h3>Daily, every other day</h3>";
9
+ $recurrence = array('recurrence_start_date' => '2009-02-10', 'recurrence_end_date' => '2009-03-10', 'recurrence_freq'=>'daily' , 'recurrence_interval' => 2);
10
+ $matching_days = dbem_get_recurrence_events($recurrence);
11
+
12
+ print_r($recurrence);
13
+ //echo "<br/>every_N = $every_N - month_position = $month_position";
14
+ echo "<br/>";
15
+ echo "<ul>";
16
+ foreach($matching_days as $day) {
17
+ echo"<li>".date("D d M Y", $day)."</li>";
18
+ }
19
+ echo "</ul>";
20
+
21
+ echo "<h3>Weekly</h3>";
22
+ $recurrence = array('recurrence_start_date' => '2009-02-10', 'recurrence_end_date' => '2009-04-24', 'recurrence_freq'=>'weekly', 'recurrence_byday'=>7 , 'recurrence_interval' => 3);
23
+ $matching_days = dbem_get_recurrence_events($recurrence);
24
+
25
+ print_r($recurrence);
26
+ //echo "<br/>every_N = $every_N - month_position = $month_position";
27
+ echo "<br/>";
28
+ echo "<ul>";
29
+ foreach($matching_days as $day) {
30
+ echo"<li>".date("D d M Y", $day)."</li>";
31
+ }
32
+ echo "</ul>";
33
+
34
+ echo "<h3>Monthly, second week</h3>";
35
+ $recurrence = array('recurrence_start_date' => '2009-02-10', 'recurrence_end_date' => '2009-04-24', 'recurrence_freq'=>'monthly', 'recurrence_byday' => 7, 'recurrence_byweekno'=>2 , 'recurrence_interval' => 1);
36
+ $matching_days = dbem_get_recurrence_events($recurrence);
37
+
38
+ print_r($recurrence);
39
+ //echo "<br/>every_N = $every_N - month_position = $month_position";
40
+ echo "<br/>";
41
+ echo "<ul>";
42
+ foreach($matching_days as $day) {
43
+ echo"<li>".date("D d M Y", $day)."</li>";
44
+ }
45
+ echo "</ul>";
46
+
47
+ echo "<h3>Last week of the month</h3>";
48
+ $recurrence = array('recurrence_start_date' => '2009-02-10', 'recurrence_end_date' => '2009-04-24', 'recurrence_freq'=>'monthly', 'recurrence_byday' => 7, 'recurrence_byweekno'=> -1 , 'recurrence_interval' => 1);
49
+ $matching_days = dbem_get_recurrence_events($recurrence);
50
+
51
+ print_r($recurrence);
52
+ //echo "<br/>every_N = $every_N - month_position = $month_position";
53
+ echo "<br/>";
54
+ echo "<ul>";
55
+ foreach($matching_days as $day) {
56
+ echo"<li>".date("D d M Y", $day)."</li>";
57
+ }
58
+ echo "</ul>";
59
+ }
60
+
61
+ function dbem_get_recurrence_events($recurrence){
62
+
63
+ //print_r($recurrence);
64
+ $start_date = mktime(0, 0, 0, substr($recurrence['recurrence_start_date'],5,2), substr($recurrence['recurrence_start_date'],8,2), substr($recurrence['recurrence_start_date'],0,4));
65
+ $end_date = mktime(0, 0, 0, substr($recurrence['recurrence_end_date'],5,2), substr($recurrence['recurrence_end_date'],8,2), substr($recurrence['recurrence_end_date'],0,4));
66
+
67
+ $every_keys = array('every' => 1, 'every_second' => 2, 'every_third' => 3, 'every_fourth' => 4);
68
+ $every_N = $every_keys[$recurrence['recurrence_modifier']];
69
+
70
+ $month_position_keys = array('first_of_month'=>1, 'second_of_month' => 2, 'third_of_month' => 3, 'fourth_of_month' => 4);
71
+ $month_position = $month_position_keys[$recurrence['recurrence_modifier']];
72
+
73
+ $last_week_start = array(25, 22, 25, 24, 25, 24, 25, 25, 24, 25, 24, 25);
74
+
75
+ $weekdays = explode(",", $recurrence['recurrence_byday']);
76
+ //print_r($weekdays);
77
+
78
+ $weekcounter = 0;
79
+ $daycounter = 0;
80
+ $counter = 0;
81
+ $cycle_date = $start_date;
82
+ $matching_days = array();
83
+ $aDay = 86400; // a day in seconds
84
+
85
+
86
+ while (date("d-M-Y", $cycle_date) != date('d-M-Y', $end_date + $aDay)) {
87
+ //echo (date("d-M-Y", $cycle_date));
88
+ $style = "";
89
+ $monthweek = floor(((date("d", $cycle_date)-1)/7))+1;
90
+ if($recurrence['recurrence_freq'] == 'daily') {
91
+
92
+ if($counter % $recurrence['recurrence_interval'] == 0 )
93
+ array_push($matching_days, $cycle_date);
94
+ $counter++;
95
+ }
96
+
97
+ if (in_array(dbem_iso_N_date_value($cycle_date), $weekdays )) {
98
+ $monthday = date("j", $cycle_date);
99
+ $month = date("n", $cycle_date);
100
+
101
+ if($recurrence['recurrence_freq'] == 'weekly') {
102
+
103
+ if($counter % $recurrence['recurrence_interval'] == 0 )
104
+ array_push($matching_days, $cycle_date);
105
+ $counter++;
106
+ }
107
+ if($recurrence['recurrence_freq'] == 'monthly') {
108
+
109
+ if(($recurrence['recurrence_byweekno'] == -1) && ($monthday >= $last_week_start[$month-1])) {
110
+ if ($counter % $recurrence['recurrence_interval'] == 0)
111
+ array_push($matching_days, $cycle_date);
112
+ $counter++;
113
+ } elseif($recurrence['recurrence_byweekno'] == $monthweek) {
114
+ if ($counter % $recurrence['recurrence_interval'] == 0)
115
+ array_push($matching_days, $cycle_date);
116
+ $counter++;
117
+ }
118
+ }
119
+ $weekcounter++;
120
+ }
121
+ $daycounter++;
122
+ $cycle_date = $cycle_date + $aDay; //adding a day
123
+
124
+ }
125
+
126
+ // print_r($matching_days);
127
+
128
+ return $matching_days ;
129
+
130
+ }
131
+
132
+
133
+
134
+ ///////////////////////////////////////////////
135
+
136
+
137
+ function dbem_insert_recurrent_event($event, $recurrence ){
138
+
139
+ global $wpdb;
140
+ $recurrence_table = $wpdb->prefix.RECURRENCE_TBNAME;
141
+
142
+ if (true) {//TODO add recurrence validation
143
+ //$wpdb->show_errors(true);
144
+
145
+ $wpdb->insert($recurrence_table, $recurrence);
146
+ //print_r($recurrence);
147
+ $recurrence['recurrence_id'] = mysql_insert_id();
148
+ $output = "<h2>Recurring</h2>";
149
+ //echo "recurrence_id = $recurrence_id<br/>";
150
+ dbem_insert_events_for_recurrence($recurrence);
151
+
152
+
153
+ }
154
+ }
155
+ function dbem_insert_events_for_recurrence($recurrence) {
156
+ global $wpdb;
157
+ $events_table = $wpdb->prefix.EVENTS_TBNAME;
158
+ $matching_days = dbem_get_recurrence_events($recurrence);
159
+ //print_r($matching_days);
160
+ sort($matching_days);
161
+
162
+ foreach($matching_days as $day) {
163
+ $new_event['event_name'] = $recurrence['recurrence_name'];
164
+ $new_event['event_start_time'] = $recurrence['recurrence_start_time'];
165
+ $new_event['event_end_time'] = $recurrence['recurrence_end_time'];
166
+ $new_event['event_rsvp'] = $recurrence['recurrence_rsvp'];
167
+ $new_event['event_seats'] = $recurrence['recurrence_seats'];
168
+ $new_event['location_id'] = $recurrence['location_id'];
169
+ $new_event['recurrence_id'] = $recurrence['recurrence_id'];
170
+ $new_event['event_start_date'] = date("Y-m-d", $day);
171
+ //print_r($new_event);
172
+ echo "<br/>";
173
+ $wpdb->insert($events_table, $new_event);
174
+ if(DEBUG)
175
+ echo date("D d M Y", $day)."<br/>";
176
+ }
177
+ }
178
+ function dbem_update_recurrence($recurrence) {
179
+ global $wpdb;
180
+ $recurrence_table = $wpdb->prefix.RECURRENCE_TBNAME;
181
+ $where = array('recurrence_id' => $recurrence['recurrence_id']);
182
+ if (true) {
183
+ $wpdb->print_error(true);
184
+ $wpdb->update($recurrence_table, $recurrence, $where);
185
+ dbem_remove_events_for_recurrence_id($recurrence['recurrence_id']);
186
+ dbem_insert_events_for_recurrence($recurrence);
187
+ return true;
188
+ }
189
+ return false;
190
+
191
+ }
192
+ function dbem_remove_events_for_recurrence_id($recurrence_id) {
193
+ global $wpdb;
194
+ $events_table = $wpdb->prefix.EVENTS_TBNAME;
195
+ $sql = "DELETE FROM $events_table WHERE recurrence_id = '$recurrence_id';";
196
+ $wpdb->query($sql);
197
+
198
+ }
199
+ function dbem_get_recurrence($recurrence_id) {
200
+ global $wpdb;
201
+ $recurrence_table = $wpdb->prefix.RECURRENCE_TBNAME;
202
+ $sql = "SELECT *,
203
+ DATE_FORMAT(recurrence_start_time, '%k') AS 'recurrence_hh',
204
+ DATE_FORMAT(recurrence_start_time, '%i') AS 'recurrence_mm',
205
+ DATE_FORMAT(recurrence_start_time, '%h:%i%p') AS 'recurrence_start_12h_time',
206
+ DATE_FORMAT(recurrence_start_time, '%H:%i') AS 'recurrence_start_24h_time',
207
+ DATE_FORMAT(recurrence_end_time, '%Y-%m-%e') AS 'event_end_date',
208
+ DATE_FORMAT(recurrence_end_time, '%k') AS 'recurrence_end_hh',
209
+ DATE_FORMAT(recurrence_end_time, '%i') AS 'recurrence_end_mm',
210
+ DATE_FORMAT(recurrence_end_time, '%h:%i%p') AS 'recurrence_end_12h_time',
211
+ DATE_FORMAT(recurrence_end_time, '%H:%i') AS 'recurrence_end_24h_time'
212
+ FROM $recurrence_table WHERE recurrence_id = $recurrence_id;";
213
+ $recurrence = $wpdb->get_row($sql, ARRAY_A);
214
+ $location = dbem_get_location($recurrence['location_id']);
215
+ $recurrence['location_name'] = $location['location_name'];
216
+ $recurrence['location_address'] = $location['location_address'];
217
+ $recurrence['location_town'] = $location['location_town'];
218
+ $recurrence['recurrence_description'] = dbem_build_recurrence_description($recurrence);
219
+ return $recurrence;
220
+ }
221
+
222
+ function dbem_build_recurrence_description($recurrence) {
223
+
224
+ $weekdays_name = array(__('Monday'),__('Tuesday'),__('Wednesday'),__('Thursday'),__('Friday'),__('Saturday'),__('Sunday'));
225
+ $monthweek_name = array('1' => __('the first %s of the month', 'dbem'),'2' => __('the second %s of the month', 'dbem'), '3' => __('the third %s of the month', 'dbem'), '4' => __('the fourth %s of the month', 'dbem'), '-1' => __('the last %s of the month', 'dbem'));
226
+ $output = sprintf (__('From %1$s to %2$s', 'dbem'), $recurrence['recurrence_start_date'], $recurrence['recurrence_end_date']).", ";
227
+ if ($recurrence['recurrence_freq'] == 'daily') {
228
+
229
+ $freq_desc =__('everyday', 'dbem');
230
+ if ($recurrence['recurrence_interval'] > 1 ) {
231
+ $freq_desc = sprintf (__("every %s days", 'dbem'), $recurrence['recurrence_interval']);
232
+ }
233
+ }
234
+ if ($recurrence['recurrence_freq'] == 'weekly') {
235
+ $weekday_array = explode(",", $recurrence['recurrence_byday']);
236
+ $natural_days = array();
237
+ foreach($weekday_array as $day)
238
+ array_push($natural_days, $weekdays_name[$day-1]);
239
+ $output .= implode(" and ", $natural_days);
240
+ if ($recurrence['recurrence_interval'] > 1 ) {
241
+ $freq_desc = ", ".sprintf (__("every %s weeks", 'dbem'), $recurrence['recurrence_interval']);
242
+ }
243
+
244
+ }
245
+ if ($recurrence['recurrence_freq'] == 'monthly') {
246
+ $weekday_array = explode(",", $recurrence['recurrence_byday']);
247
+ $natural_days = array();
248
+ foreach($weekday_array as $day)
249
+ array_push($natural_days, $weekdays_name[$day-1]);
250
+ $freq_desc = sprintf (($monthweek_name[$recurrence['recurrence_byweekno']]), implode(" and ", $natural_days));
251
+ if ($recurrence['recurrence_interval'] > 1 ) {
252
+ $freq_desc .= ", ".sprintf (__("every %s months",'dbem'), $recurrence['recurrence_interval']);
253
+ }
254
+
255
+ }
256
+ $output .= $freq_desc;
257
+ return $output;
258
+ }
259
+ function dbem_iso_N_date_value($date) {
260
+ // date("N", $cycle_date)
261
+ $n = date("w", $date);
262
+ if ($n == 0)
263
+ $n = 7;
264
+ return $n;
265
+ }
266
+ ?>
dbem.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $j=jQuery.noConflict();
2
+
3
+ function remove_booking() {
4
+ eventId = ($j(this).parents('table:first').attr('id').split("-"))[3];
5
+ idToRemove = ($j(this).parents('tr:first').attr('id').split("-"))[1];
6
+ $j.ajax({
7
+ type: "POST",
8
+ url: "admin.php?page=people&action=remove_booking",
9
+ data: "booking_id="+ idToRemove,
10
+ success: function(){
11
+
12
+ $j('tr#booking-' + idToRemove).fadeOut('slow');
13
+ update_booking_data();
14
+ }
15
+ });
16
+
17
+
18
+ }
19
+
20
+ function update_booking_data () {
21
+ $j.getJSON("admin.php?page=people&dbem_ajax_action=booking_data",{id: eventId, ajax: 'true'}, function(data){
22
+ booked = data[0].bookedSeats;
23
+ available = data[0].availableSeats;
24
+ $j('td#booked-seats').text(booked);
25
+ $j('td#available-seats').text(available);
26
+ });
27
+ }
28
+
29
+ $j(document).ready( function() {
30
+ // Managing bookings delete operations
31
+ $j('a.bookingdelbutton').click(remove_booking);
32
+ });
dbem_UI_helpers.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function dbem_option_items($array, $saved_value) {
3
+ $output = "";
4
+ foreach($array as $key => $item) {
5
+ $selected ='';
6
+ if ($key == $saved_value)
7
+ $selected = "selected='selected'";
8
+ $output .= "<option value='$key' $selected >$item</option>\n";
9
+
10
+ }
11
+ echo $output;
12
+ }
13
+
14
+ function dbem_checkbox_items($name, $array, $saved_values, $horizontal = true) {
15
+ $output = "";
16
+ foreach($array as $key => $item) {
17
+
18
+ $checked = "";
19
+ if (in_array($key, $saved_values))
20
+ $checked = "checked='checked'";
21
+ $output .= "<input type='checkbox' name='$name' value='$key' $checked /> $item ";
22
+ if(!$horizontal)
23
+ $output .= "<br/>\n";
24
+ }
25
+ echo $output;
26
+
27
+ }
28
+
29
+ function dbem_options_input_text($title, $name, $description) {
30
+ ?>
31
+ <tr valign="top" id='<?php echo $name;?>_row'>
32
+ <th scope="row"><?php _e($title, 'dbem') ?></th>
33
+ <td>
34
+ <input name="<?php echo $name ?>" type="text" id="<?php echo $title ?>" style="width: 95%" value="<?php echo get_option($name); ?>" size="45" /><br />
35
+ <?php _e($description, 'dbem') ?>
36
+ </td>
37
+ </tr>
38
+ <?php
39
+ }
40
+ function dbem_options_input_password($title, $name, $description) {
41
+ ?>
42
+ <tr valign="top" id='<?php echo $name;?>_row'>
43
+ <th scope="row"><?php _e($title, 'dbem') ?></th>
44
+ <td>
45
+ <input name="<?php echo $name ?>" type="password" id="<?php echo $title ?>" style="width: 95%" value="<?php echo get_option($name); ?>" size="45" /><br />
46
+ <?php echo $description; ?>
47
+ </td>
48
+ </tr>
49
+ <?php
50
+ }
51
+
52
+ function dbem_options_textarea($title, $name, $description) {
53
+ ?>
54
+ <tr valign="top" id='<?php echo $name;?>_row'>
55
+ <th scope="row"><?php _e($title,'dbem')?></th>
56
+ <td><textarea name="<?php echo $name ?>" id="<?php echo $name ?>" rows="6" cols="60"><?php echo (get_option($name));?></textarea><br/>
57
+ <?php echo $description; ?></td>
58
+ </tr>
59
+ <?php
60
+ }
61
+
62
+ function dbem_options_radio_binary($title, $name, $description) {
63
+ $list_events_page = get_option($name); ?>
64
+
65
+ <tr valign="top" id='<?php echo $name;?>_row'>
66
+ <th scope="row"><?php _e($title,'dbem'); ?></th>
67
+ <td>
68
+ <input id="<?php echo $name ?>_yes" name="<?php echo $name ?>" type="radio" value="1" <?php if($list_events_page) echo "checked='checked'"; ?> /><?php _e('Yes'); ?> <br />
69
+ <input id="<?php echo $name ?>_no" name="<?php echo $name ?>" type="radio" value="0" <?php if(!$list_events_page) echo "checked='checked'"; ?> /><?php _e('No'); ?> <br />
70
+ <?php echo $description; ?>
71
+ </td>
72
+ </tr>
73
+ <?php
74
+ }
75
+ function dbem_options_select($title, $name, $list, $description) {
76
+ $option_value = get_option($name); ?>
77
+
78
+ <tr valign="top" id='<?php echo $name;?>_row'>
79
+ <th scope="row"><?php _e($title,'dbem'); ?></th>
80
+ <td>
81
+ <select name="<?php echo $name; ?>" >
82
+ <?php foreach($list as $key => $value) {
83
+ $key == $option_value ? $selected = "selected='selected' " : $selected = '';
84
+ echo "<option value='$key' $selected>$value</option>";
85
+ } ?>
86
+ </select> <br/>
87
+ <?php echo $description; ?>
88
+ </td>
89
+ </tr>
90
+ <?php
91
+ }
92
+
93
+ ?>
dbem_calendar.php CHANGED
@@ -1,8 +1,22 @@
1
  <?php
2
 
3
- function dbem_get_calendar($month="") {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- global $wpdb;
6
  // if (!($month))
7
  $date = mktime(0,0,0,date('m'), date('d'), date('Y'));
8
  $day = date('d', $date);
@@ -112,13 +126,15 @@ function dbem_get_calendar($month="") {
112
 
113
  $calendar="<div id='dbem-calendar'>";
114
 
 
 
115
  // Build the heading portion of the calendar table
116
  $calendar .= "<table id='dbem-calendar-table'>\n".
117
  "<thead>\n<tr>\n".
118
  "<td colspan='7'>$month_name $year</td>\n".
119
  "</tr>\n</thead>\n".
120
  "<tr class='days-names'>\n".
121
- "<td>".__('M_Monday_initial')."</td><td>".__('T_Tuesday_initial')."</td><td>".__('W_Wednesday_initial')."</td><td>".__('T_Thursday_initial')."</td><td>".__('F_Friday_initial')."</td><td>".__('S_Saturday_initial')."</td><td>".__('S_Sunday_initial')."</td>\n".
122
  "</tr>\n";
123
 
124
  // Now we break each key of the array
@@ -179,44 +195,48 @@ function dbem_get_calendar($month="") {
179
  $year_pre=$year;
180
  $year_post=$year;
181
  }
182
- $limit_pre=mktime(0,0,0,$month_pre, 1 , $year_pre);
183
- $limit_post=mktime(0,0,0,$month_post, 30 , $year_post);
184
- $events=$wpdb->get_results("SELECT event_id,
 
185
  event_name,
186
- event_venue,
187
- event_town,
188
- event_province,
189
- event_time,
190
- DATE_FORMAT(event_time, '%w') AS 'event_weekday_n',
191
- DATE_FORMAT(event_time, '%e') AS 'event_day',
192
- DATE_FORMAT(event_time, '%c') AS 'event_month_n',
193
- DATE_FORMAT(event_time, '%Y') AS 'event_year',
194
- DATE_FORMAT(event_time, '%k') AS 'event_hh',
195
- DATE_FORMAT(event_time, '%i') AS 'event_mm'
196
- FROM ".$wpdb->prefix."events WHERE UNIX_TIMESTAMP(event_time) > $limit_pre AND UNIX_TIMESTAMP(event_time) < $limit_post ORDER BY event_time");
197
  //----- DEBUG ------------
198
  //foreach($events as $event) { //DEBUG
199
  // $calendar .= ("$event->event_day / $event->event_month_n - $event->event_name<br/>");
200
  //}
201
  // ------------------
202
- // inserts the events
 
203
  $events_page = get_option('dbem_events_page');
204
  if($events){
205
  foreach($events as $event) {
206
  if ($event->event_month_n == $month_pre) {
207
- $calendar=str_replace("<td class='eventless-pre'>$event->event_day</td>","<td class='eventful-pre'><a href='?page_id=$events_page&amp;event_id="."$event->event_id'>$event->event_day</a></td>",$calendar);
208
  } elseif($event->event_month_n == $month_post) {
209
- $calendar=str_replace("<td class='eventless-post'>$event->event_day</td>","<td class='eventful-post'><a href='?page_id=$events_page&amp;event_id="."$event->event_id'>$event->event_day</a></td>",$calendar);
210
  } elseif($event->event_day == $day) {
211
- $calendar=str_replace("<td class='eventless-today'>$event->event_day</td>","<td class='eventful-today'><a href='?page_id=$events_page&amp;event_id="."$event->event_id'>$event->event_day</a></td>",$calendar);
212
  } else{
213
- $calendar=str_replace("<td class='eventless'>$event->event_day</td>","<td class='eventful'><a href='?page_id=$events_page&amp;event_id="."$event->event_id'>$event->event_day</a></td>",$calendar);
214
  }
215
  }
216
  }
217
  $output=$calendar;
218
-
219
- echo $output;
 
 
220
  }
221
 
222
  function dbem_days_in_month($month, $year) {
@@ -275,5 +295,7 @@ function dbem_calendar_style() {
275
  }
276
  add_action('wp_head', 'dbem_calendar_style');
277
 
278
-
 
 
279
  ?>
1
  <?php
2
 
3
+ function dbem_get_calendar_shortcode($atts) {
4
+ $result = dbem_get_calendar("echo=0");
5
+ return $result;
6
+ }
7
+ add_shortcode('events_calendar', 'dbem_get_calendar_shortcode');
8
+
9
+ function dbem_get_calendar($args="") {
10
+ $defaults = array(
11
+ 'month' => '',
12
+ 'echo' => 1
13
+ );
14
+ $r = wp_parse_args( $args, $defaults );
15
+ extract( $r, EXTR_SKIP );
16
+ $month = $r['month'];
17
+ $echo = $r['echo'];
18
 
19
+ global $wpdb;
20
  // if (!($month))
21
  $date = mktime(0,0,0,date('m'), date('d'), date('Y'));
22
  $day = date('d', $date);
126
 
127
  $calendar="<div id='dbem-calendar'>";
128
 
129
+ $days_initials = "<td>".dbem_translate_and_trim("Monday")."</td><td>".dbem_translate_and_trim("Tuesday")."</td><td>".dbem_translate_and_trim("Wednesday")."</td><td>".dbem_translate_and_trim("Thursday")."</td><td>".dbem_translate_and_trim("Friday")."</td><td>".dbem_translate_and_trim("Saturday")."</td><td>".dbem_translate_and_trim("Sunday")."</td>\n";
130
+
131
  // Build the heading portion of the calendar table
132
  $calendar .= "<table id='dbem-calendar-table'>\n".
133
  "<thead>\n<tr>\n".
134
  "<td colspan='7'>$month_name $year</td>\n".
135
  "</tr>\n</thead>\n".
136
  "<tr class='days-names'>\n".
137
+ $days_initials.
138
  "</tr>\n";
139
 
140
  // Now we break each key of the array
195
  $year_pre=$year;
196
  $year_post=$year;
197
  }
198
+ $limit_pre=date("Y-m-d", mktime(0,0,0,$month_pre, 1 , $year_pre));
199
+ $limit_post=date("Y-m-d", mktime(0,0,0,$month_post, 30 , $year_post));
200
+ $events_table = $wpdb->prefix.EVENTS_TBNAME;
201
+ $sql = "SELECT event_id,
202
  event_name,
203
+ event_start_date,
204
+ DATE_FORMAT(event_start_date, '%w') AS 'event_weekday_n',
205
+ DATE_FORMAT(event_start_date, '%e') AS 'event_day',
206
+ DATE_FORMAT(event_start_date, '%c') AS 'event_month_n',
207
+ DATE_FORMAT(event_start_time, '%Y') AS 'event_year',
208
+ DATE_FORMAT(event_start_time, '%k') AS 'event_hh',
209
+ DATE_FORMAT(event_start_time, '%i') AS 'event_mm'
210
+ FROM $events_table WHERE event_start_date BETWEEN '$limit_pre' AND '$limit_post' ORDER BY event_start_date";
211
+
212
+ $events=$wpdb->get_results($sql);
213
+
214
  //----- DEBUG ------------
215
  //foreach($events as $event) { //DEBUG
216
  // $calendar .= ("$event->event_day / $event->event_month_n - $event->event_name<br/>");
217
  //}
218
  // ------------------
219
+ // inserts the events
220
+
221
  $events_page = get_option('dbem_events_page');
222
  if($events){
223
  foreach($events as $event) {
224
  if ($event->event_month_n == $month_pre) {
225
+ $calendar=str_replace("<td class='eventless-pre'>$event->event_day</td>","<td class='eventful-pre'><a href='?page_id=$events_page&amp;calendar_day="."$event->event_start_date'>$event->event_day</a></td>",$calendar);
226
  } elseif($event->event_month_n == $month_post) {
227
+ $calendar=str_replace("<td class='eventless-post'>$event->event_day</td>","<td class='eventful-post'><a href='?page_id=$events_page&amp;calendar_day="."$event->event_start_date'>$event->event_day</a></td>",$calendar);
228
  } elseif($event->event_day == $day) {
229
+ $calendar=str_replace("<td class='eventless-today'>$event->event_day</td>","<td class='eventful-today'><a href='?page_id=$events_page&amp;calendar_day="."$event->event_start_date'>$event->event_day</a></td>",$calendar);
230
  } else{
231
+ $calendar=str_replace("<td class='eventless'>$event->event_day</td>","<td class='eventful'><a href='?page_id=$events_page&amp;calendar_day="."$event->event_start_date'>$event->event_day</a></td>",$calendar);
232
  }
233
  }
234
  }
235
  $output=$calendar;
236
+ if ($echo)
237
+ echo $output;
238
+ else
239
+ return $output;
240
  }
241
 
242
  function dbem_days_in_month($month, $year) {
295
  }
296
  add_action('wp_head', 'dbem_calendar_style');
297
 
298
+ function dbem_translate_and_trim($string, $length = 1) {
299
+ return substr(__($string), 0, $length);
300
+ }
301
  ?>
dbem_events.php ADDED
@@ -0,0 +1,1832 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ function dbem_new_event_page() {
5
+
6
+ $title=__("Insert New Event", 'dbem');
7
+ $event = dbem_get_event($element);
8
+ dbem_event_form($event, $title, $element);
9
+
10
+ }
11
+
12
+ function dbem_events_subpanel() {
13
+ global $wpdb;
14
+ $action=$_GET['action'];
15
+ $action2 =$_GET['action2'];
16
+ $event_ID=$_GET['event_id'];
17
+ $recurrence_ID=$_GET['recurrence_id'];
18
+ $scope=$_GET['scope'];
19
+ $offset=$_GET['offset'];
20
+ $order=$_GET['order'];
21
+ $selectedEvents = $_GET['events'];
22
+
23
+ // Disable Hello to new user if requested
24
+ if(isset($_GET['disable_hello_to_user']) && $_GET['disable_hello_to_user'] == 'true')
25
+ update_option('dbem_hello_to_user', 0);
26
+
27
+ if ($order == "")
28
+ $order = "ASC";
29
+ if ($offset=="")
30
+ $offset = "0";
31
+ $event_table_name = $wpdb->prefix.EVENTS_TBNAME;
32
+ // Debug code, to make sure I get the correct page
33
+
34
+
35
+
36
+
37
+ // DELETE action
38
+ if ($action == 'deleteEvents') {
39
+ // $sql="DELETE FROM ".$event_table_name." WHERE event_id='"."$event_ID"."'";
40
+
41
+ // TODO eventual error if ID in non-existant
42
+ //$wpdb->query($sql);
43
+ foreach($selectedEvents as $event_ID) {
44
+ dbem_delete_event($event_ID);
45
+ }
46
+
47
+ $events = dbem_get_events("", "future");
48
+ dbem_events_table($events, 10,"Future events");
49
+ }
50
+ // UPDATE or CREATE action
51
+ if ($action == 'update_event' || $action == 'update_recurrence') {
52
+
53
+ $event = array();
54
+ $location = array();
55
+
56
+ $event['event_name']=stripslashes($_POST[event_name]);
57
+ // Set event end time to event time if not valid
58
+ // if (!_dbem_is_date_valid($event['event_end_date']))
59
+ // $event['event_end_date'] = $event['event-date'];
60
+ $event['event_start_date'] = $_POST[event_date];
61
+ $event['event_end_date'] = $_POST[event_end_date];
62
+ //$event['event_start_time'] = $_POST[event_hh].":".$_POST[event_mm].":00";
63
+ //$event['event_end_time'] = $_POST[event_end_hh].":".$_POST[event_end_mm].":00";
64
+ $event['event_start_time'] = date("G:i:00", strtotime($_POST['event_start_time']));
65
+ $event['event_end_time'] = date("G:i:00", strtotime($_POST['event_end_time']));
66
+ $recurrence['recurrence_name'] = $event['event_name'];
67
+ $recurrence['recurrence_start_date'] = $event['event_start_date'];
68
+ $recurrence['recurrence_end_date'] = $event['event_end_date'];
69
+ $recurrence['recurrence_start_time'] = $event['event_start_time'];
70
+ $recurrence['recurrence_end_time'] = $event['event_end_time'];
71
+ $recurrence['recurrence_id'] = $_POST[recurrence_id];
72
+ $recurrence['recurrence_freq'] = $_POST[recurrence_freq];
73
+ $recurrence['recurrence_freq'] == 'weekly'
74
+ ? $recurrence[recurrence_byday] = implode(",", $_POST['recurrence_bydays'])
75
+ : $recurrence['recurrence_byday'] = $_POST[recurrence_byday];
76
+ $_POST['recurrence_interval'] == "" ? $recurrence['recurrence_interval'] = 1 : $recurrence['recurrence_interval'] = $_POST['recurrence_interval'];
77
+ $recurrence['recurrence_byweekno'] = $_POST[recurrence_byweekno];
78
+
79
+
80
+ $event['event_rsvp'] = $_POST['event_rsvp'];
81
+ $event['event_seats'] = $_POST['event_seats'];
82
+
83
+ if(isset($_POST['event_contactperson_id']) && $_POST['event_contactperson_id'] != '' && $_POST['event_contactperson_id'] != '-1') {
84
+
85
+ $event['event_contactperson_id'] = $_POST['event_contactperson_id'];
86
+ $recurrence['event_contactperson_id'] = $_POST['event_contactperson_id'];
87
+ }
88
+
89
+ if(!_dbem_is_time_valid($event_end_time))
90
+ $event_end_time = $event_time;
91
+
92
+ $location['location_name']=$_POST[location_name];
93
+ $location['location_address']=$_POST[location_address];
94
+ $location['location_town']=$_POST[location_town];
95
+ $location['location_latitude']=$_POST[location_latitude];
96
+ $location['location_longitude']=$_POST[location_longitude];
97
+ $location['location_description']="";
98
+ $event['event_notes']=stripslashes($_POST[event_notes]);
99
+ $recurrence['recurrence_notes']=$_POST[event_notes];
100
+ $validation_result = dbem_validate_event($event);
101
+
102
+
103
+ if (true) { //RESETME( $validation_result == "OK") {
104
+ // validation successful
105
+
106
+ $related_location = dbem_get_identical_location($location);
107
+ // print_r($related_location);
108
+ if ($related_location) {
109
+ $event['location_id'] = $related_location['location_id'];
110
+ $recurrence['location_id'] = $related_location['location_id'];
111
+ }
112
+ else {
113
+
114
+ $new_location = dbem_insert_location($location);
115
+ $event['location_id']= $new_location['location_id'];
116
+ $recurrence['location_id'] = $new_location['location_id'];
117
+ //print_r($new_location);
118
+
119
+ }
120
+
121
+ if(!$event_ID && !$recurrence_ID ) {
122
+ // there isn't anything
123
+ if ($_POST[repeated_event]) {
124
+
125
+ //insert new recurrence
126
+ dbem_insert_recurrent_event($event,$recurrence);
127
+ $feedback_message = __('New recurrent event inserted!','dbem');
128
+ } else {
129
+ // INSERT new event
130
+ $wpdb->insert($event_table_name, $event);
131
+ $feedback_message = __('New event successfully inserted!','dbem');
132
+ }
133
+ } else {
134
+ // something exists
135
+ if($recurrence_ID) {
136
+ // UPDATE old recurrence
137
+ $recurrence['recurrence_id'] = $recurrence_ID;
138
+ //print_r($recurrence);
139
+ if(dbem_update_recurrence($recurrence))
140
+ $feedback_message = __('Recurrence updated!','dbem');
141
+ else
142
+ $feedback_message = __('Something went wrong with the recurrence update...','dbem');
143
+
144
+ } else {
145
+ // UPDATE old event
146
+ // unlink from recurrence in case it was generated by one
147
+ $event['recurrence_id'] = null;
148
+ $where['event_id'] = $event_ID;
149
+ $wpdb->update($event_table_name, $event, $where);
150
+ $feedback_message = "'".$event['event_name']."' ".__('updated','dbem')."!";
151
+ }
152
+ }
153
+
154
+
155
+
156
+
157
+ //$wpdb->query($sql);
158
+ echo "<div id='message' class='updated fade'>
159
+ <p>$feedback_message</p>
160
+ </div>";
161
+ $events = dbem_get_events("", "future");
162
+ dbem_events_table($events, 10, "Future events");
163
+ } else {
164
+ // validation unsuccessful
165
+
166
+ echo "<div id='message' class='error '>
167
+ <p>".__("Ach, there's a problem here:","dbem")." $validation_result</p>
168
+ </div>";
169
+ dbem_event_form($event,"Edit event $event_ID" ,$event_ID);
170
+
171
+ }
172
+ }
173
+ if ($action == 'edit_event') {
174
+ if (!$event_ID) {
175
+ $title=__("Insert New Event", 'dbem');
176
+ } else {
177
+ $event = dbem_get_event($event_ID);
178
+ $title=__("Edit Event", 'dbem')." '".$event['event_name']."'";
179
+ }
180
+
181
+ //$event=$wpdb->get_row($sql, ARRAY_A);
182
+ // Enter new events and updates old ones
183
+ // DEBUG: echo"Nome: $event->event_name";
184
+
185
+
186
+ dbem_event_form($event, $title, $event_ID);
187
+
188
+ }
189
+ if ($action == 'edit_recurrence') {
190
+
191
+ $event_ID = $_GET['recurrence_id'];
192
+ $recurrence = dbem_get_recurrence($event_ID);
193
+ $title=__("Reschedule", 'dbem'). " '" .$recurrence['recurrence_name']."'";
194
+ dbem_event_form($recurrence, $title, $event_ID);
195
+
196
+ }
197
+
198
+ if ($action == 'update_recurrence') {
199
+ //print_r($recurrence);
200
+ //die('update recurrence!');
201
+ }
202
+
203
+ if ($action == "-1" || $action ==""){
204
+ // No action, only showing the events list
205
+
206
+
207
+
208
+ switch ($scope) {
209
+ case "past":
210
+ $title = __('Past Events','dbem');
211
+ break;
212
+ case "all":
213
+ $title = __('All Events','dbem');
214
+ break;
215
+ default:
216
+ $title = __('Future Events','dbem');
217
+ $scope = "future";
218
+ }
219
+ $limit = 20;
220
+ $events = dbem_get_events($limit, $scope, $order,$offset);
221
+
222
+ dbem_events_table($events, $limit, $title);
223
+
224
+ }
225
+
226
+
227
+ }
228
+
229
+ // Function composing the options subpanel
230
+ function dbem_options_subpanel() {
231
+ // dbem_options_register();
232
+
233
+ ?>
234
+ <div class="wrap">
235
+
236
+ <div id='icon-options-general' class='icon32'>
237
+ <br/>
238
+ </div>
239
+ <h2><?php _e('Event Manager Options','dbem'); ?></h2>
240
+ <form id="dbem_options_form" method="post" action="options.php">
241
+
242
+ <h3><?php _e('Events format', 'dbem');?></h3>
243
+ <table class="form-table">
244
+ <?php
245
+ dbem_options_textarea(__('Default event list format', 'dbem'), 'dbem_event_list_item_format', __('The format of any events in a list.<br/>Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_LOCATION</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_NOTES</code>.<br/> Use <code>#_LINKEDNAME</code> for the event name with a link to the given event page.<br/> Use <code>#_EVENTPAGEURL</code> to print the event page URL and make your own customised links.<br/> Use <code>#_LOCATIONPAGEURL</code> to print the location page URL and make your own customised links.<br/>To insert date and time values, use <a href="http://www.php.net/manual/en/function.date.php">PHP time format characters</a> with a <code>#</code> symbol before them, i.e. <code>#m</code>, <code>#M</code>, <code>#j</code>, etc.<br/> For the end time, put <code>#@</code> in front of the character, ie. <code>#@h</code>, <code>#@i</code>, etc.<br/> Feel free to use HTML tags as <code>li</code>, <code>br</code> and so on.', 'dbem'));
246
+ dbem_options_input_text(__('Single event page title format','dbem'), 'dbem_event_page_title_format', __('The format of a single event page title. Follow the previous formatting instructions.','dbem'));
247
+ dbem_options_textarea(__('Default single event format','dbem'), 'dbem_single_event_format',__('The format of a single event page.<br/>Follow the previous formatting instructions. <br/>Use <code>#_MAP</code> to insert a map.<br/>Use <code>#_CONTACTNAME</code>, <code>#_CONTACTEMAIL</code>, <code>#_CONTACTPHONE</code> to insert respectively the name, e-mail address and phone number of the designated contact person. <br/>Use <code>#_ADDBOOKINGFORM</code> to insert a form to allow the user to respond to your events reserving one or more places (RSVP).<br/> Use <code>#_REMOVEBOOKINGFORM</code> to insert a form where users, inserting their name and e-mail address, can remove their bookings.','dbem'));
248
+ dbem_options_radio_binary(__('Show events page in lists?','dbem'), 'dbem_list_events_page', __('Check this option if you want the events page to appear together with other pages in pages lists.','dbem'));
249
+ dbem_options_input_text(__('Events page title','dbem'),'dbem_events_page_title',__('The title on the multiple events page.','dbem'));
250
+ dbem_options_input_text(__('No events message','dbem'), 'dbem_no_events_message',__('The message displayed when no events are available.','dbem'));
251
+ dbem_options_textarea(__('Map text format','dbem'),'dbem_map_text_format',__('The format the text appearing in the event page map cloud.<br/>Follow the previous formatting instructions.','dbem'));
252
+ ?>
253
+ </table>
254
+
255
+ <h3><?php _e('Locations format', 'dbem');?></h3>
256
+ <table class="form-table"><?php
257
+ dbem_options_input_text(__('Single location page title format','dbem'),'dbem_location_page_title_format',__('The format of a single location page title.<br/>Follow the previous formatting instructions.','dbem'));
258
+ dbem_options_textarea(__('Default single location page format','dbem'),'dbem_single_location_format',__('The format of a single location page.<br/>Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_DESCRIPTION</code>.<br/> Use <code>#_MAP</code> to display a map of the event location, and <code>#_IMAGE</code> to display an image of the location.<br/> Use <code>#_NEXTEVENTS</code> to insert a list of the upcoming events, <code>#_PASTEVENTS</code> for a list of past events, <code>#_ALLEVENTS</code> for a list of all events taking place in this location.','dbem'));
259
+ dbem_options_textarea(__('Default location baloon format','dbem'),'dbem_location_baloon_format', __('The format of of the text appearing in the baloon describing the location in the map.<br/>Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_DESCRIPTION</code> or <code>#_IMAGE</code>.','dbem'));
260
+ dbem_options_textarea(__('Default location event list format','dbem'), 'dbem_location_event_list_item_format', __('The format of the events the list inserted in the location page through the <code>#_NEXTEVENTS</code>, <code>#_PASTEVENTS</code> and <code>#_ALLEVENTS</code> element. <br/> Follow the events formatting instructions','dbem'));
261
+ dbem_options_textarea(__('Default no events message', 'dbem'),'dbem_location_no_events_message', __('The message to be displayed in the list generated by <code>#_NEXTEVENTS</code>, <code>#_PASTEVENTS</code> and <code>#_ALLEVENTS</code> when no events are available.','dbem'));
262
+
263
+ ?>
264
+ </table>
265
+
266
+ <h3><?php _e('RSS feed format', 'dbem');?></h3>
267
+ <table class="form-table"><?php
268
+
269
+ dbem_options_input_text(__('RSS main title','dbem'),'dbem_rss_main_title',__('The main title of your RSS events feed.','dbem'));
270
+ dbem_options_input_text(__('RSS main description','dbem'),'dbem_rss_main_description',__('The main description of your RSS events feed.','dbem'));
271
+ dbem_options_input_text(__('RSS title format','dbem'),'dbem_rss_title_format',__('The format of the title of each item in the events RSS feed.','dbem'));
272
+ dbem_options_input_text(__('RSS description format','dbem'),'dbem_rss_description_format',__('The format of the description of each item in the events RSS feed. Follow the previous formatting instructions.','dbem')); ?>
273
+ </table>
274
+
275
+ <h3><?php _e('Maps and geotagging', 'dbem');?></h3>
276
+ <table class='form-table'>
277
+ <?php $gmap_is_active = get_option('dbem_gmap_is_active'); ?>
278
+
279
+ <tr valign="top">
280
+ <th scope="row"><?php _e('Enable Google Maps integration?','dbem'); ?></th>
281
+ <td>
282
+ <input id="dbem_gmap_is_active_yes" name="dbem_gmap_is_active" type="radio" value="1" <?php if($gmap_is_active) echo "checked='checked'"; ?> /><?php _e('Yes'); ?> <br />
283
+ <input name="dbem_gmap_is_active" type="radio" value="0" <?php if(!$gmap_is_active) echo "checked='checked'"; ?> /> <?php _e('No'); ?> <br />
284
+ <?php _e('Check this option to enable Goggle Map integration.','dbem')?>
285
+ </td>
286
+ </tr>
287
+ <?php
288
+ dbem_options_input_text(__('Google Maps API Key','dbem'), 'dbem_gmap_key', sprintf (__("To display Google Maps you need a Google Maps API key. Don't worry, it's free, you can get one <a href='%s'>here</a>.",'dbem'), 'http://code.google.com/apis/maps/signup.html'));
289
+ ?>
290
+ </table>
291
+
292
+ <h3><?php _e('RSVP and bookings', 'dbem');?></h3>
293
+ <table class='form-table'>
294
+ <?php
295
+ dbem_options_select(__('Default contact person','dbem'), 'dbem_default_contact_person', dbem_get_indexed_users(), __('Select the default contact person. This user will be employed whenever a contact person is not explicitly specified for an event','dbem'));
296
+ dbem_options_radio_binary(__('Enable the RSVP e-mail notifications?','dbem'),'dbem_rsvp_mail_notify_is_active', __('Check this option if you want to receive an email when someone books places for your events.','dbem') );
297
+ dbem_options_textarea(__('Contact person email format','dbem'),'dbem_contactperson_email_body',__('The format or the email which will be sent to the contact person. Follow the events formatting instructions. <br/>Use <code>#_RESPNAME</code>, <code>#_RESPEMAIL</code> and <code>#_RESPPHONE</code> to display respectively the name, e-mail, address and phone of the respondent.<br/>Use <code>#_SPACES</code> to display the number of spaces reserved by the respondent.<br/> Use <code>#_BOOKEDSEATS</code> and <code>#_AVAILABLESEATS</code> to display respectively the number of booked and available seats.','dbem'));
298
+ dbem_options_textarea(__('Contact person email format','dbem'),'dbem_respondent_email_body',__('The format or the email which will be sent to reposdent. Follow the events formatting instructions. <br/>Use <code>#_RESPNAME</code> to display the name of the respondent.<br/>Use <code>#_CONTACTNAME</code> and <code>#_CONTACTMAIL</code> a to display respectively the name and e-mail of the contact person.<br/>Use <code>#_SPACES</code> to display the number of spaces reserved by the respondent.','dbem'));
299
+ dbem_options_input_text(__('Notification sender name','dbem'),'dbem_mail_sender_name', __("Insert the display name of the notification sender.",'dbem'));
300
+ dbem_options_input_text(__('Notification sender address','dbem'),'dbem_mail_sender_address', __("Insert the address of the notification sender. It must corresponds with your gmail account user",'dbem'));
301
+ dbem_options_input_text(__('Default notification receiver address','dbem'),'dbem_mail_receiver_address',__("Insert the address of the receiver of your notifications",'dbem'));
302
+ dbem_options_input_text('Mail sending port','dbem_rsvp_mail_port',__("The port through which you e-mail notifications will be sent. Make sure the firewall doesn't block this port",'dbem'));
303
+ dbem_options_select(__('Mail sending method','dbem'), 'dbem_rsvp_mail_send_method', array('smtp'=>'SMTP','mail'=>__('PHP mail function', 'dbem'), 'sendmail' => 'Sendmail', 'qmail' => 'Qmail'), __('Select the method to send email notification.','dbem'));
304
+ dbem_options_radio_binary(__('Use SMTP authentication?','dbem'),'dbem_rsvp_mail_SMTPAuth', __('SMTP authenticatio is often needed. If you use GMail, make sure to set this parameter to Yes','dbem'));
305
+ dbem_options_input_text('SMTP host','dbem_smtp_host',__("The SMTP host. Usually it corresponds to 'localhost'. If you use GMail, set this value to 'ssl://smtp.gmail.com:465'.",'dbem'));
306
+ dbem_options_input_text(__('SMTP username','dbem'),'dbem_smtp_username', __("Insert the username to be used to access your SMTP server.",'dbem'));
307
+ dbem_options_input_password(__('SMTP password','dbem'),"dbem_smtp_password", __("Insert the password to be used to access your SMTP server",'dbem'));?>
308
+
309
+
310
+
311
+ </table>
312
+
313
+ <h3><?php _e('Images size', 'dbem');?></h3>
314
+ <table class='form-table'> <?php
315
+ dbem_options_input_text(__('Maximum width (px)','dbem'),'dbem_image_max_width',__('The maximum allowed width for images uploades','dbem'));
316
+ dbem_options_input_text(__('Maximum height (px)','dbem'),'dbem_image_max_height', __("The maximum allowed width for images uploaded, in pixels",'dbem'));
317
+ dbem_options_input_text(__('Maximum size (bytes)','dbem'),'dbem_image_max_size', __("The maximum allowed size for images uploaded, in pixels",'dbem'));
318
+ ?>
319
+ </table>
320
+
321
+
322
+
323
+ <p class="submit">
324
+ <input type="submit" id="dbem_options_submit" name="Submit" value="<?php _e('Save Changes') ?>" />
325
+ </p>
326
+
327
+
328
+ <?php settings_fields('dbem-options'); ?>
329
+ </form>
330
+ </div>
331
+ <?php
332
+
333
+
334
+ }
335
+
336
+
337
+
338
+
339
+ //This is the content of the event page
340
+ function dbem_events_page_content() {
341
+ global $wpdb;
342
+ if (isset($_REQUEST['location_id']) && $_REQUEST['location_id'] |= '') {
343
+
344
+ $location= dbem_get_location($_REQUEST['location_id']);
345
+ $single_location_format = get_option('dbem_single_location_format');
346
+ $page_body = dbem_replace_locations_placeholders($single_location_format, $location);
347
+ return $page_body;
348
+
349
+ }
350
+ if (isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '') {
351
+ // single event page
352
+ $event_ID=$_REQUEST['event_id'];
353
+ $event= dbem_get_event($event_ID);
354
+ $single_event_format = get_option('dbem_single_event_format');
355
+ $page_body = dbem_replace_placeholders($single_event_format, $event);
356
+ return $page_body;
357
+ } elseif (isset($_REQUEST['calendar_day']) && $_REQUEST['calendar_day'] != ''){
358
+
359
+ $date = $_REQUEST['calendar_day'];
360
+ $events_N = dbem_events_count_for($date);
361
+ // $_GET['scope'] ? $scope = $_GET['scope']: $scope = "future";
362
+ // $stored_format = get_option('dbem_event_list_item_format');
363
+ // $events_body = dbem_get_events_list(10, $scope, "ASC", $stored_format, $false);
364
+ if ($events_N > 1) {
365
+ $_GET['calendar_day'] ? $scope = $_GET['calendar_day']: $scope = "future";
366
+ $stored_format = get_option('dbem_event_list_item_format');
367
+ $events_body = "<ul class='dbem_events_list'>".dbem_get_events_list(10, $scope, "ASC", $stored_format, $false)."</ul>";
368
+ return $events_body;
369
+ } else {
370
+ $events = dbem_get_events("",$_REQUEST['calendar_day']);
371
+ $event= $events[0];
372
+ $single_event_format = get_option('dbem_single_event_format');
373
+ $page_body = dbem_replace_placeholders($single_event_format, $event);
374
+ return $page_body;
375
+ }
376
+ return $events_body;
377
+ } else {
378
+ // Multiple events page
379
+ $_GET['scope'] ? $scope = $_GET['scope']: $scope = "future";
380
+ $stored_format = get_option('dbem_event_list_item_format');
381
+ $events_body = $events_body = "<ul class='dbem_events_list'>".dbem_get_events_list(10, $scope, "ASC", $stored_format, $false)."</ul>";
382
+ return $events_body;
383
+
384
+ }
385
+ }
386
+ function dbem_events_count_for($date) {
387
+ global $wpdb;
388
+ $table_name = $wpdb->prefix .EVENTS_TBNAME;
389
+ $sql = "SELECT COUNT(*) FROM $table_name WHERE event_start_date like '$date';";
390
+ return $wpdb->get_var($sql);
391
+ }
392
+
393
+ // filter function to call the event page when appropriate
394
+ function dbem_filter_events_page($data) {
395
+
396
+ // $table_name = $wpdb->prefix .EVENTS_TBNAME;
397
+ // $start = strpos($data, DBEM_PAGE);
398
+
399
+ $is_events_post = (get_the_ID() == get_option('dbem_events_page'));
400
+ $events_page_id = get_option('dbem_events_page');
401
+ if (is_page($events_page_id) && $is_events_post) {
402
+ return dbem_events_page_content();
403
+ } else {
404
+ return $data;
405
+ }
406
+ }
407
+ add_filter('the_content','dbem_filter_events_page');
408
+
409
+ function dbem_events_page_title($data) {
410
+ $events_page_id = get_option('dbem_events_page');
411
+ $events_page = get_page($events_page_id);
412
+ $events_page_title = $events_page->post_title;
413
+
414
+
415
+
416
+ if (($data == $events_page_title) && (is_page($events_page_id))) {
417
+ if (isset($_REQUEST['calendar_day']) && $_REQUEST['calendar_day'] != ''){
418
+
419
+ $date = $_REQUEST['calendar_day'];
420
+ $events_N = dbem_events_count_for($date);
421
+
422
+ if ($events_N == 1) {
423
+ $events = dbem_get_events("",$_REQUEST['calendar_day']);
424
+ $event= $events[0];
425
+ $stored_page_title_format = get_option('dbem_event_page_title_format');
426
+ $page_title = dbem_replace_placeholders($stored_page_title_format, $event);
427
+ return $page_title;
428
+ }
429
+
430
+ }
431
+
432
+
433
+
434
+
435
+ if (isset($_REQUEST['location_id']) && $_REQUEST['location_id'] |= '') {
436
+ $location= dbem_get_location($_REQUEST['location_id']);
437
+ $stored_page_title_format = get_option('dbem_location_page_title_format');
438
+ $page_title = dbem_replace_locations_placeholders($stored_page_title_format, $location);
439
+ return $page_title;
440
+ }
441
+ if (isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '') {
442
+ // single event page
443
+ $event_ID=$_REQUEST['event_id'];
444
+ $event= dbem_get_event($event_ID);
445
+ $stored_page_title_format = get_option('dbem_event_page_title_format');
446
+ $page_title = dbem_replace_placeholders($stored_page_title_format, $event);
447
+ return $page_title;
448
+ } else {
449
+ // Multiple events page
450
+ $page_title = get_option('dbem_events_page_title');
451
+ return $page_title;
452
+
453
+ }
454
+
455
+
456
+
457
+
458
+ } else {
459
+ return $data;
460
+ }
461
+
462
+ }
463
+ // to make sure that in pages lists the title is dbem_events_page_title, and not overwritten by the previous filter
464
+ add_filter('the_title','dbem_events_page_title');
465
+ add_filter('single_post_title','dbem_events_page_title');
466
+
467
+ function dbem_filter_get_pages($data) {
468
+ $output = array();
469
+ $events_page_id = get_option('dbem_events_page');
470
+ for ($i = 0; $i < count($data); ++$i) {
471
+ if ($data[$i]->ID == $events_page_id) {
472
+ $list_events_page = get_option('dbem_list_events_page');
473
+ if($list_events_page) {
474
+ $data[$i]->post_title = get_option('dbem_events_page_title')."&nbsp;";
475
+ $output[] = $data[$i];
476
+ }
477
+ } else {
478
+ $output[] = $data[$i];
479
+ }
480
+ }
481
+ return $output;
482
+ }
483
+ add_filter('get_pages', 'dbem_filter_get_pages');
484
+
485
+
486
+
487
+ //
488
+ // TODO: ROBA NUOVA DA RIORDINARE
489
+ // ADMIN CSS for debug
490
+ function dbem_admin_css() {
491
+ $css = "
492
+ <style type='text/css'>
493
+ .debug{
494
+ color: green;
495
+ background: #B7F98C;
496
+ margin: 15px;
497
+ padding: 10px;
498
+ border: 1px solid #629948;
499
+ }
500
+ .switch-tab {
501
+ background: #aaa;
502
+ width: 100px;
503
+ float: right;
504
+ text-align: center;
505
+ margin: 3px 1px 0 5px;
506
+ padding: 2px;
507
+ }
508
+ .switch-tab a {
509
+ color: #fff;
510
+ text-decoration: none;
511
+ }
512
+ .switch-tab a:hover {
513
+ color: #D54E21;
514
+
515
+ }
516
+ #events-pagination {
517
+ text-align: center;
518
+
519
+ }
520
+ #events-pagination a {
521
+ margin: 0 20px 0 20px;
522
+ text-decoration: none;
523
+ width: 80px;
524
+ padding: 3px 0;
525
+ background: #FAF4B7;
526
+ border: 1px solid #ccc;
527
+ border-top: none;
528
+ }
529
+ #new-event {
530
+ float: left;
531
+
532
+ }
533
+ </style>";
534
+ echo $css;
535
+ }
536
+
537
+ add_action('admin_print_scripts','dbem_admin_css');
538
+
539
+ // TEMPLATE TAGS
540
+
541
+ // exposed function, for theme makers
542
+ function dbem_get_events_list($limit="3", $scope="future", $order="ASC", $format='', $echo=1) {
543
+ if(strpos($limit, "=")) {
544
+ // allows the use of arguments without breaking the legacy code
545
+ $defaults = array(
546
+ 'limit' => 3,
547
+ 'scope' => 'future',
548
+ 'order' => 'ASC',
549
+ 'format' => '',
550
+ 'echo' => 1
551
+ );
552
+
553
+ $r = wp_parse_args( $limit, $defaults );
554
+ extract( $r, EXTR_SKIP );
555
+ $limit = $r['limit'];
556
+ $scope = $r['scope'];
557
+ $order = $r['order'];
558
+ $format = $r['format'];
559
+ $echo = $r['echo'];
560
+ }
561
+ if ($scope == "")
562
+ $scope = "future";
563
+ if ($order != "DESC")
564
+ $order = "ASC";
565
+ if ($format == '')
566
+ $format = get_option('dbem_event_list_item_format');
567
+ $events = dbem_get_events($limit, $scope, $order);
568
+ $output = "";
569
+ if (!empty($events)) {
570
+ foreach ($events as $event){
571
+ // $localised_date = mysql2date("j M Y", $event->event_time);
572
+
573
+
574
+
575
+ $output .= dbem_replace_placeholders($format, $event);
576
+ }
577
+ } else {
578
+ $output = "<li class='dbem-no-events'>".get_option('dbem_no_events_message')."</li>";
579
+ }
580
+ if ($echo)
581
+ echo $output;
582
+ else
583
+ return $output;
584
+ }
585
+
586
+ function dbem_get_events_list_shortcode($atts) {
587
+ extract(shortcode_atts(array(
588
+ 'limit' => 3,
589
+ 'scope' => 'future',
590
+ 'order' => 'ASC',
591
+ 'format'=> '',
592
+ ), $atts));
593
+ $result = dbem_get_events_list("limit=$limit&scope=$scope&order=$order&format=$format&echo=0") ;
594
+ return $result;
595
+ }
596
+ add_shortcode('events_list', 'dbem_get_events_list_shortcode');
597
+
598
+
599
+
600
+
601
+ function dbem_get_events_page($justurl=0, $echo=1, $text='') {
602
+ if(strpos($justurl, "=")) {
603
+ // allows the use of arguments without breaking the legacy code
604
+ $defaults = array(
605
+ 'justurl' => 0,
606
+ 'text' => '',
607
+ 'echo' => 1,
608
+ );
609
+
610
+ $r = wp_parse_args( $justurl, $defaults );
611
+ extract( $r, EXTR_SKIP );
612
+ $justurl = $r['justurl'];
613
+ $text = $r['text'];
614
+ $echo = $r['echo'];
615
+ }
616
+
617
+ $page_link = get_permalink(get_option("dbem_events_page")) ;
618
+ if($justurl) {
619
+ $result = $page_link;
620
+ } else {
621
+ if ($text=='')
622
+ $text = get_option("dbem_events_page_title") ;
623
+ $result = "<a href='$page_link' title='$text'>$text</a>";
624
+ }
625
+ if ($echo)
626
+ echo $result;
627
+ else
628
+ return $result;
629
+
630
+ }
631
+ function dbem_get_events_page_shortcode($atts) {
632
+ extract(shortcode_atts(array(
633
+ 'justurl' => 0,
634
+ 'text' => '',
635
+ ), $atts));
636
+ $result = dbem_get_events_page("justurl=$justurl&text=$text&echo=0") ;
637
+ return $result;
638
+ }
639
+ add_shortcode('events_page', 'dbem_get_events_page_shortcode');
640
+
641
+
642
+
643
+ function dbem_are_events_available($scope="future") {
644
+ if ($scope == "")
645
+ $scope = "future";
646
+ $events = dbem_get_events(1, $scope);
647
+
648
+ if (empty($events))
649
+ return FALSE;
650
+ else
651
+ return TRUE ;
652
+ }
653
+
654
+ // Returns true if the page in question is the events page
655
+ function dbem_is_events_page() {
656
+ $events_page_id = get_option('dbem_events_page');
657
+ return is_page($events_page_id);
658
+ }
659
+
660
+ function dbem_is_single_event_page() {
661
+ return (dbem_is_events_page() && (isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '')) ;
662
+ }
663
+
664
+ function dbem_is_multiple_events_page() {
665
+ return (dbem_is_events_page() && !(isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '')) ;
666
+ }
667
+
668
+
669
+ // main function querying the database event table
670
+ function dbem_get_events($limit="",$scope="future",$order="ASC", $offset="", $location_id = "") {
671
+ global $wpdb;
672
+
673
+ $events_table = $wpdb->prefix.EVENTS_TBNAME;
674
+ if ($limit != "")
675
+ $limit = "LIMIT $limit";
676
+ if ($offset != "")
677
+ $offset = "OFFSET $offset";
678
+ if($order="")
679
+ $order="ASC";
680
+
681
+ $timestamp = time();
682
+ $date_time_array = getdate($timestamp);
683
+ $hours = $date_time_array['hours'];
684
+ $minutes = $date_time_array['minutes'];
685
+ $seconds = $date_time_array['seconds'];
686
+ $month = $date_time_array['mon'];
687
+ $day = $date_time_array['mday'];
688
+ $year = $date_time_array['year'];
689
+ $today = strftime('%Y-%m-%d', mktime($hours,$minutes,$seconds,$month,$day,$year));
690
+
691
+ $conditions = array();
692
+ if(preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $scope)) {
693
+ $conditions[] = " event_start_date like '$scope'" ;
694
+ } else {
695
+ if (($scope != "past") && ($scope !="all"))
696
+ $scope = "future";
697
+ if ($scope == "future")
698
+ $conditions[] = " event_start_date >= '$today'" ;
699
+ if ($scope == "past")
700
+ $conditions[] = " event_start_date < '$today'" ;
701
+ }
702
+
703
+ if($location_id != "")
704
+ $conditions[] = " location_id = $location_id";
705
+
706
+ $where = implode(" AND ", $conditions);
707
+ if ($where != "")
708
+ $where = " WHERE ".$where;
709
+
710
+ $sql = "SELECT event_id,
711
+ event_name,
712
+ DATE_FORMAT(event_start_time, '%e') AS 'event_day',
713
+ DATE_FORMAT(event_start_time, '%Y') AS 'event_year',
714
+ DATE_FORMAT(event_start_time, '%k') AS 'event_hh',
715
+ DATE_FORMAT(event_start_time, '%i') AS 'event_mm',
716
+ DATE_FORMAT(event_end_time, '%e') AS 'event_end_day',
717
+ DATE_FORMAT(event_end_time, '%Y') AS 'event_end_year',
718
+ DATE_FORMAT(event_end_time, '%k') AS 'event_end_hh',
719
+ DATE_FORMAT(event_end_time, '%i') AS 'event_end_mm',
720
+ event_start_date,
721
+ event_end_date,
722
+ event_start_time,
723
+ event_end_time,
724
+ event_notes,
725
+ event_rsvp,
726
+ recurrence_id,
727
+ location_id,
728
+ event_contactperson_id
729
+ FROM $events_table
730
+ $where
731
+ ORDER BY event_start_date $order
732
+ $limit
733
+ $offset";
734
+
735
+ $wpdb->show_errors = true;
736
+ $events = $wpdb->get_results($sql, ARRAY_A);
737
+ if (!empty($events)) {
738
+ //$wpdb->print_error();
739
+ $inflated_events = array();
740
+ foreach($events as $this_event) {
741
+
742
+ $this_location = dbem_get_location($this_event['location_id']);
743
+ $this_event['location_name'] = $this_location['location_name'];
744
+ $this_event['location_address'] = $this_location['location_address'];
745
+ $this_event['location_town'] = $this_location['location_town'];
746
+ array_push($inflated_events, $this_event);
747
+ }
748
+
749
+ return $inflated_events;
750
+ } else {
751
+ return null;
752
+ }
753
+ }
754
+ function dbem_get_event($event_id) {
755
+ global $wpdb;
756
+ $events_table = $wpdb->prefix.EVENTS_TBNAME;
757
+ $sql = "SELECT event_id,
758
+ event_name,
759
+ DATE_FORMAT(event_start_date, '%Y-%m-%e') AS 'event_date',
760
+ DATE_FORMAT(event_start_date, '%e') AS 'event_day',
761
+ DATE_FORMAT(event_start_date, '%m') AS 'event_month',
762
+ DATE_FORMAT(event_start_date, '%Y') AS 'event_year',
763
+ DATE_FORMAT(event_start_time, '%k') AS 'event_hh',
764
+ DATE_FORMAT(event_start_time, '%i') AS 'event_mm',
765
+ DATE_FORMAT(event_start_time, '%h:%i%p') AS 'event_start_12h_time',
766
+ DATE_FORMAT(event_start_time, '%H:%i') AS 'event_start_24h_time',
767
+ DATE_FORMAT(event_end_time, '%Y-%m-%e') AS 'event_end_date',
768
+ DATE_FORMAT(event_end_time, '%e') AS 'event_end_day',
769
+ DATE_FORMAT(event_end_time, '%m') AS 'event_end_month',
770
+ DATE_FORMAT(event_end_time, '%Y') AS 'event_end_year',
771
+ DATE_FORMAT(event_end_time, '%k') AS 'event_end_hh',
772
+ DATE_FORMAT(event_end_time, '%i') AS 'event_end_mm',
773
+ DATE_FORMAT(event_end_time, '%h:%i%p') AS 'event_end_12h_time',
774
+ DATE_FORMAT(event_end_time, '%H:%i') AS 'event_end_24h_time',
775
+ event_start_date,
776
+ event_end_date,
777
+ event_start_time,
778
+ event_end_time,
779
+ event_notes,
780
+ event_rsvp,
781
+ event_seats,
782
+ recurrence_id,
783
+ location_id,
784
+ event_contactperson_id
785
+ FROM $events_table
786
+ WHERE event_id = $event_id";
787
+
788
+ //$wpdb->show_errors(true);
789
+ $event = $wpdb->get_row($sql,ARRAY_A);
790
+ //$wpdb->print_error();
791
+ $location = dbem_get_location($event['location_id']);
792
+ $event['location_name'] = $location['location_name'];
793
+ $event['location_address'] = $location['location_address'];
794
+ $event['location_town'] = $location['location_town'];
795
+ $event['location_latitude'] = $location['location_latitude'];
796
+ $event['location_longitude'] = $location['location_longitude'];
797
+ $event['location_image_url'] = $location['location_image_url'];
798
+ return $event;
799
+ }
800
+
801
+ function dbem_hello_to_new_user() {
802
+ $current_user = wp_get_current_user();
803
+ $advice = sprintf(__("<p>Hey, <strong>%s</strong>, welcome to <strong>Events Manager</strong>! We hope you like it around here.</p>
804
+ <p>Now it's time to insert events lists through <a href='%s' title='Widgets page'>widgets</a>, <a href='%s' title='Template tags documentation'>template tags</a> or <a href='%s' title='Shortcodes documentation'>shortcodes</a>.</p>
805
+ <p>By the way, have you taken a look at the <a href='%s' title='Change settings'>Settings page</a>? That's where you customize the way events and locations are displayed.</p>
806
+ <p>What? Tired of seeing this advice? I hear you, <a href='%s' title='Don't show this advice again'>click here</a> and you won't see this again!</p>", 'dbem'),
807
+ $current_user->display_name,
808
+ get_bloginfo('url').'/wp-admin/widgets.php',
809
+ 'http://davidebenini.it/wordpress-plugins/events-manager#template-tags',
810
+ 'http://davidebenini.it/wordpress-plugins/events-manager#shortcodes',
811
+ get_bloginfo('url').'/wp-admin/admin.php?page=events-manager-options',
812
+ get_bloginfo('url').'/wp-admin/admin.php?page=events-manager/events-manager.php&disable_hello_to_user=true');
813
+ ?>
814
+ <div id="message" class="updated">
815
+ <?php echo $advice; ?>
816
+ </div>
817
+ <?php
818
+ }
819
+
820
+ function dbem_events_table($events, $limit, $title) {
821
+ if (isset($_GET['scope']))
822
+ $scope = $_GET['scope'];
823
+ else
824
+ $scope = "future";
825
+ if (($scope != "past") && ($scope != "all"))
826
+ $scope = "future";
827
+ $events_count = count(dbem_get_events("",$scope));
828
+
829
+ if (isset($_GET['offset']))
830
+ $offset = $_GET['offset'];
831
+
832
+ $use_events_end = get_option('dbem_use_event_end');
833
+
834
+ ?>
835
+
836
+ <div class="wrap">
837
+ <div id="icon-events" class="icon32"><br/></div>
838
+ <h2><?php echo $title; ?></h2>
839
+
840
+ <?php
841
+ $say_hello = get_option('dbem_hello_to_user');
842
+ if ($say_hello == 1)
843
+ dbem_hello_to_new_user();
844
+
845
+ ?>
846
+ <!--<div id='new-event' class='switch-tab'><a href="<?php bloginfo('wpurl')?>/wp-admin/edit.php?page=events-manager/events-manager.php&amp;action=edit_event"><?php _e('New Event ...', 'dbem');?></a></div>-->
847
+ <?php
848
+
849
+ $link = array();
850
+ $link['past'] = "<a href='".get_bloginfo('url')."/wp-admin/edit.php?page=events-manager/events-manager.php&amp;scope=past&amp;order=desc'>".__('Past events','dbem')."</a>";
851
+ $link['all'] = " <a href='".get_bloginfo('url')."/wp-admin/edit.php?page=events-manager/events-manager.php&amp;scope=all&amp;order=desc'>".__('All events','dbem')."</a>";
852
+ $link['future'] = " <a href='".get_bloginfo('url')."/wp-admin/edit.php?page=events-manager/events-manager.php&amp;scope=future'>".__('Future events','dbem')."</a>";
853
+
854
+ $scope_names = array();
855
+ $scope_names['past'] = __('Past events','dbem');
856
+ $scope_names['all'] = __('All events','dbem');
857
+ $scope_names['future'] = __('Future events','dbem');
858
+
859
+ ?>
860
+
861
+ <form id="posts-filter" action="" method="get">
862
+ <input type='hidden' name='page' value='events-manager/events-manager.php'/>
863
+ <ul class="subsubsub">
864
+ <li><a href='edit.php' class="current"><? _e('Total', 'dbem');?> <span class="count">(<?php echo (count($events));?>)</span></a> </li></ul>
865
+
866
+
867
+ <div class="tablenav">
868
+
869
+ <div class="alignleft actions">
870
+ <select name="action">
871
+ <option value="-1" selected="selected"><?php _e('Bulk Actions');?></option>
872
+ <option value="deleteEvents"><?php _e('Delete selected');?></option>
873
+
874
+ </select>
875
+ <input type="submit" value="<? _e('Apply'); ?>" name="doaction2" id="doaction2" class="button-secondary action" />
876
+ <select name="scope">
877
+
878
+ <?php
879
+ foreach ($scope_names as $key => $value) {
880
+ $selected = "";
881
+ if ($key == $scope)
882
+ $selected = "selected='selected'";
883
+ echo "<option value='$key' $selected>$value</option> ";
884
+ }
885
+ ?>
886
+ </select>
887
+ <input id="post-query-submit" class="button-secondary" type="submit" value="<?php _e('Filter')?>"/>
888
+ </div>
889
+ <div class="clear">
890
+ </div>
891
+ <?php
892
+ if (empty($events)) {
893
+ // TODO localize
894
+ echo "no events";
895
+ } else {
896
+ ?>
897
+
898
+ <table class="widefat">
899
+ <thead>
900
+ <tr>
901
+ <th class='manage-column column-cb check-column' scope='col'><input class='select-all' type="checkbox" value='1'/></th>
902
+ <th><?php _e('Name', 'dbem');?></th>
903
+ <th><?php _e('Location', 'dbem');?></th>
904
+
905
+
906
+ <th colspan="2"><?php _e('Date and time', 'dbem');?></th>
907
+
908
+
909
+
910
+ </tr>
911
+ </thead>
912
+ <tbody>
913
+ <?php
914
+ $i =1;
915
+ foreach ($events as $event){
916
+ $class = ($i % 2) ? ' class="alternate"' : '';
917
+ // FIXME set to american
918
+ $localised_date = mysql2date(__('D d M Y'), $event['event_start_date']);
919
+ $style = "";
920
+ $today = date("Y-m-d");
921
+
922
+ $location_summary = "<b>".$event['location_name']."</b><br/>".$event['location_address']." - ".$event['location_town'];
923
+
924
+
925
+ if ($event['event_start_date'] < $today )
926
+ $style= "style ='background-color: #FADDB7;'";
927
+ ?>
928
+ <tr <?php echo"$class $style"; ?> >
929
+
930
+ <td>
931
+ <input type='checkbox' class='row-selector' value='<?php echo $event['event_id'];?>' name='events[]'/>
932
+ </td>
933
+ <td>
934
+ <strong><a class="row-title" href="<?php bloginfo('wpurl')?>/wp-admin/edit.php?page=events-manager/events-manager.php&amp;action=edit_event&amp;event_id=<?php echo $event['event_id']; ?>"><?php echo ($event['event_name']); ?></a></strong>
935
+ </td>
936
+ <td>
937
+
938
+ <?php echo $location_summary; ?>
939
+
940
+ </td>
941
+
942
+ <td>
943
+ <?php echo $localised_date ; ?><br/>
944
+
945
+ <?php echo substr($event['event_start_time'],0,5)." - ".substr($event['event_end_time'],0,5) ; ?>
946
+ </td>
947
+ <td>
948
+ <?php if($event['recurrence_id']) {
949
+ $recurrence = dbem_get_recurrence($event[recurrence_id]); ?>
950
+
951
+ <b><?php echo $recurrence['recurrence_description'];?> <br/> <a href="<?php bloginfo('wpurl')?>/wp-admin/edit.php?page=events-manager/events-manager.php&amp;action=edit_recurrence&amp;recurrence_id=<?php echo $recurrence['recurrence_id'];?>"><?php _e('Reschedule','dbem');?></a></b>
952
+
953
+
954
+ <?php } ?>
955
+ </td>
956
+
957
+
958
+ <?php
959
+ echo'</tr>';
960
+ $i++;
961
+ }
962
+ ?>
963
+
964
+ </tbody>
965
+ </table>
966
+ <?php } // end of table?>
967
+
968
+ <div class='tablenav'>
969
+ <div class="alignleft actions">
970
+
971
+
972
+ <br class='clear'/>
973
+ </div>
974
+ <br class='clear'/>
975
+ </div>
976
+ </form>
977
+ </div>
978
+ </div>
979
+
980
+ <?php
981
+ if ($events_count > $limit) {
982
+ $backward = $offset + $limit;
983
+ $forward = $offset - $limit;
984
+ if (DEBUG)
985
+ echo "COUNT = $count BACKWARD = $backward FORWARD = $forward<br> -- OFFSET = $offset" ;
986
+ echo "<div id='events-pagination'> ";
987
+ if ($backward < $events_count)
988
+ echo "<a style='float: left' href='".get_bloginfo('url')."/wp-admin/edit.php?page=eventmanager.php&amp;scope=$scope&offset=$backward'>&lt;&lt;</a>" ;
989
+ if ($forward >= 0)
990
+ echo "<a style='float: right' href='".get_bloginfo('url')."/wp-admin/edit.php?page=eventmanager.php&amp;scope=$scope&offset=$forward'>&gt;&gt;</a>";
991
+ echo "</div>" ;
992
+ }
993
+ ?>
994
+
995
+ </div>
996
+ <?php
997
+ }
998
+ function dbem_event_form($event, $title, $element) {
999
+
1000
+ global $localised_date_formats;
1001
+ // change prefix according to event/recurrence
1002
+ $_GET['action'] == "edit_recurrence" ? $pref = "recurrence_" : $pref = "event_";
1003
+
1004
+ $_GET['action'] == "edit_recurrence"
1005
+ ? $form_destination= "edit.php?page=events-manager/events-manager.php&amp;action=update_recurrence&amp;recurrence_id=".$element
1006
+ : $form_destination = "edit.php?page=events-manager/events-manager.php&amp;action=update_event&amp;event_id=".$element;
1007
+
1008
+
1009
+ $locale_code = substr(get_locale(), 0, 2);
1010
+ $localised_date_format = $localised_date_formats[$locale_code];
1011
+
1012
+ $hours_locale = "24";
1013
+ // Setting 12 hours format for those countries using it
1014
+ if(preg_match("/en|sk|zh|us|uk/",$locale_code))
1015
+ $hours_locale = "12";
1016
+
1017
+
1018
+
1019
+ $localised_example = str_replace("yy", "2008", str_replace("mm", "11", str_replace("dd", "28", $localised_date_format)));
1020
+ $localised_end_example = str_replace("yy", "2008", str_replace("mm", "11", str_replace("dd", "28", $localised_date_format)));
1021
+
1022
+ if ($event[$pref.'start_date'] != "") {
1023
+ preg_match("/(\d{4})-(\d{2})-(\d{2})/",$event[$pref.'start_date'], $matches );
1024
+ $year = $matches[1];
1025
+ $month = $matches[2];
1026
+ $day = $matches[3];
1027
+ $localised_date = str_replace("yy", $year, str_replace("mm", $month, str_replace("dd", $day, $localised_date_format)));
1028
+ } else {
1029
+ $localised_date = "";
1030
+ }
1031
+ if ($event[$pref.'end_date'] != "") {
1032
+ preg_match("/(\d{4})-(\d{2})-(\d{2})/",$event[$pref.'end_date'], $matches );
1033
+ $end_year = $matches[1];
1034
+ $end_month = $matches[2];
1035
+ $end_day = $matches[3];
1036
+ $localised_end_date = str_replace("yy", $end_year, str_replace("mm", $end_month, str_replace("dd", $end_day, $localised_date_format)));
1037
+ } else {
1038
+ $localised_end_date = "";
1039
+ }
1040
+ // if($event[$pref.'rsvp'])
1041
+ // echo (dbem_bookings_table($event[$pref.'id']));
1042
+
1043
+
1044
+ $freq_options = array("daily" => __('Daily', 'dbem'), "weekly" => __('Weekly','dbem'),"monthly" => __('Monthly','dbem'));
1045
+ $days_names = array(1 => __('Mon'), 2 => __('Tue'), 3 =>__('Wed'), 4 =>__('Thu'), 5 =>__('Fri'), 6 =>__('Sat'), 7 =>__('Sun'));
1046
+ $saved_bydays = explode(",", $event['recurrence_byday']);
1047
+ $weekno_options = array("1" => __('first', 'dbem'), '2' => __('second','dbem'),'3'=>__('third','dbem'),'4'=>__('fourth', 'dbem'), '-1'=>__('last','dbem'));
1048
+
1049
+ $event[$pref.'rsvp'] ? $event_RSVP_checked = "checked='checked'" : $event_RSVP_checked ='';
1050
+
1051
+ ?>
1052
+ <form id="eventForm" method="post" action="<?php echo $form_destination; ?>">
1053
+ <div class="wrap">
1054
+ <div id="icon-events" class="icon32"><br/></div>
1055
+ <h2><?php echo $title; ?></h2>
1056
+ <?php
1057
+ if($event['recurrence_id']) { ?>
1058
+ <p id='recurrence_warning'>
1059
+ <?php if(isset($_GET['action']) && ($_GET['action'] == 'edit_recurrence')) {
1060
+ _e('WARNING: This is a recurrence.', 'dbem')?><br/>
1061
+ <?php _e('Modifying these data all the events linked to this recurrence will be rescheduled','dbem');
1062
+
1063
+ } else {
1064
+ _e('WARNING: This is a recurring event.', 'dbem');
1065
+ _e('If you change these data and save, this will become an independent event.','dbem');
1066
+ }?></p>
1067
+ <?php } ?>
1068
+ <div id="poststuff" class="metabox-holder">
1069
+
1070
+
1071
+ <!-- SIDEBAR -->
1072
+ <div id="side-info-column" class="inner-sidebar">
1073
+ <div id='side-sortables' class='meta-box-sortables'>
1074
+ <!-- recurrence postbox -->
1075
+ <div class="postbox " >
1076
+ <div class="handlediv" title="Fare clic per cambiare."><br /></div>
1077
+ <h3 class='hndle'><span><?php _e("Recurrence",'dbem');?></span></h3>
1078
+
1079
+ <div class="inside">
1080
+ <?php
1081
+ if(!$event['event_id']) {
1082
+ ?>
1083
+ <?php if($event['recurrence_id'] != "")
1084
+ $recurrence_YES = "checked='checked'";
1085
+
1086
+
1087
+ ?>
1088
+ <p><input id="event-recurrence" type="checkbox" name="repeated_event" value="1" <?php echo $recurrence_YES;?> /> <?php _e('Repeated event', 'dbem');?></p>
1089
+ <div id="event_recurrence_pattern">
1090
+ <p>Frequency:
1091
+ <select id="recurrence-frequency" name="recurrence_freq">
1092
+ <?php dbem_option_items($freq_options, $event[$pref.'freq']); ?>
1093
+ </select></p>
1094
+ <p>
1095
+ <?php _e('Every', 'dbem')?>
1096
+ <input id="recurrence-interval" name='recurrence_interval' size='2' value='<?php echo $event['recurrence_interval'];?>'></input>
1097
+ <span class='interval-desc' id="interval-daily-singular"><?php _e('day', 'dbem') ?></span>
1098
+ <span class='interval-desc' id="interval-daily-plural"><?php _e('days', 'dbem') ?></span>
1099
+ <span class='interval-desc' id="interval-weekly-singular"><?php _e('week', 'dbem') ?></span>
1100
+ <span class='interval-desc' id="interval-weekly-plural"><?php _e('weeks', 'dbem') ?></span>
1101
+ <span class='interval-desc' id="interval-monthly-singular"><?php _e('month', 'dbem') ?></span>
1102
+ <span class='interval-desc' id="interval-monthly-plural"><?php _e('months', 'dbem') ?></span>
1103
+ </p>
1104
+
1105
+ <p class="alternate-selector" id="weekly-selector">
1106
+ <?php dbem_checkbox_items('recurrence_bydays[]', $days_names, $saved_bydays); ?>
1107
+ </p>
1108
+
1109
+ <p class="alternate-selector" id="monthly-selector">
1110
+ <?php _e('Every','dbem')?>
1111
+ <select id="monthly-modifier" name="recurrence_byweekno">
1112
+ <?php dbem_option_items($weekno_options, $event['recurrence_byweekno']);?>
1113
+ </select>
1114
+ <select id="recurrence-weekday" name="recurrence_byday">
1115
+ <?php dbem_option_items($days_names, $event['recurrence_byday']); ?>
1116
+ </select>&nbsp;
1117
+ </p>
1118
+ </div>
1119
+ <p id="recurrence-tip"><?php _e('Check if your event happens more than once according to a regular pattern', 'dbem') ?></p>
1120
+
1121
+ <?php } else {
1122
+
1123
+ if(!$event['recurrence_id']) {
1124
+ echo "<p>".__('This is\'t a recurrent event','dbem').".</p>";
1125
+ } else {
1126
+
1127
+ $recurrence = dbem_get_recurrence($event['recurrence_id']); ?>
1128
+ <p><?php echo $recurrence['recurrence_description'];?><br/><a href="<?php bloginfo('wpurl')?>/wp-admin/edit.php?page=events-manager/events-manager.php&amp;action=edit_recurrence&amp;recurrence_id=<?php echo $recurrence['recurrence_id'];?>"><?php _e('Reschedule', 'dbem');?></a></p>
1129
+
1130
+ <?php } ?>
1131
+
1132
+ <?php } ?>
1133
+ </div>
1134
+
1135
+
1136
+
1137
+ </div>
1138
+
1139
+ <div class="postbox " >
1140
+ <div class="handlediv" title="Fare clic per cambiare."><br /></div>
1141
+ <h3 class='hndle'><span><? _e('Contact Person','dbem');?></span></h3>
1142
+ <div class="inside">
1143
+ <p>Contact: <?php wp_dropdown_users(array('name'=>'event_contactperson_id', 'show_option_none'=>__("Select...",'dbem'),'selected'=>$event['event_contactperson_id'])) ; ?></p>
1144
+ </div>
1145
+ </div>
1146
+
1147
+
1148
+
1149
+ <div class="postbox " >
1150
+ <div class="handlediv" title="Fare clic per cambiare."><br /></div>
1151
+ <h3 class='hndle'><span>RSVP</span></h3>
1152
+ <div class="inside">
1153
+
1154
+ <p><input id="rsvp-checkbox" name='event_rsvp' value='1' type='checkbox' <?php echo $event_RSVP_checked ?> /> <? _e('Enable registration for this event', 'dbem')?></p>
1155
+ <div id='rsvp-data'>
1156
+ <?php
1157
+ if ($event['event_contactperson_id'] != NULL)
1158
+ $selected = $event['event_contactperson_id'];
1159
+ else
1160
+ $selected = '0';?>
1161
+ <p> <?php _e('Spaces');?>: <input id="seats-input" type="text" name="event_seats" size='5' value="<?php echo $event[$pref.'seats']?>" /></p>
1162
+ <?php dbem_bookings_compact_table($event[$pref.'id']); ?>
1163
+ </div>
1164
+ </div>
1165
+ </div>
1166
+ </div>
1167
+ </div>
1168
+
1169
+
1170
+
1171
+ <!-- END OF SIDEBAR -->
1172
+
1173
+
1174
+
1175
+ <div id="post-body" class="has-sidebar">
1176
+ <div id="post-body-content" class="has-sidebar-content">
1177
+ <div id="event_name" class="stuffbox">
1178
+ <h3><?php _e('Name','dbem'); ?></h3>
1179
+ <div class="inside">
1180
+ <input type="text" name="event_name" value="<?php echo $event[$pref.'name'] ?>" /><br/>
1181
+ <?php _e('The event name. Example: Birthday party', 'dbem') ?>
1182
+ </div>
1183
+ </div>
1184
+
1185
+
1186
+
1187
+ <div id="event_start_date" class="stuffbox">
1188
+ <h3 id='event-date-title'><?php _e('Event date','dbem'); ?></h3><h3 id='recurrence-dates-title'><?php _e('Recurrence dates','dbem'); ?></h3>
1189
+ <div class="inside">
1190
+ <input id="localised-date" type="text" name="localised_event_date" value="<?php echo $localised_date ?>" style ="display: none;" />
1191
+ <input id="date-to-submit" type="text" name="event_date" value="<?php echo $event[$pref.'start_date'] ?>" style="background: #FCFFAA" /> <input id="localised-end-date" type="text" name="localised_event_end_date" value="<?php echo $localised_end_date ?>" style ="display: none; " />
1192
+
1193
+ <input id="end-date-to-submit" type="text" name="event_end_date" value="<?php echo $event[$pref.'end_date'] ?>" style="background: #FCFFAA" />
1194
+
1195
+
1196
+ <br/>
1197
+ <span id='event-date-explanation'><?php _e('The event date.', 'dbem'); ?></span><span id='recurrence-dates-explanation'><?php _e('The recurrence beginning and end date.', 'dbem'); ?></span>
1198
+
1199
+ </div>
1200
+ </div>
1201
+
1202
+
1203
+
1204
+
1205
+
1206
+ <div id="event_end_day" class="stuffbox">
1207
+ <h3><?php _e('Event time','dbem'); ?></h3>
1208
+ <div class="inside">
1209
+ <input id="start-time" type="text" size="8" maxlength="8" name="event_start_time" value="<?php echo $event[$pref.'start_'.$hours_locale."h_time"]; ?>" /> -
1210
+ <input id="end-time" type="text" size="8" maxlength="8" name="event_end_time" value="<?php echo $event[$pref.'end_'.$hours_locale."h_time"]; ?>" /> <br/>
1211
+
1212
+
1213
+ <?php _e('The time of the event beginning and end', 'dbem') ?>.
1214
+
1215
+ </div>
1216
+ </div>
1217
+
1218
+
1219
+
1220
+ <div id="location_coordinates" class="stuffbox" style='display:none;'>
1221
+ <h3><?php _e('Coordinates','dbem'); ?></h3>
1222
+ <div class="inside">
1223
+ <input id='location-latitude' name='location_latitude' type='text' value='<?php echo $event['location_latitude']; ?>' size='15' /> - <input id='location-longitude' name='location_longitude' type='text' value='<?php echo $event['location_longitude']; ?>' size='15' />
1224
+ </div>
1225
+ </div>
1226
+
1227
+
1228
+
1229
+
1230
+ <div id="location_name" class="stuffbox">
1231
+ <h3><?php _e('Location','dbem'); ?></h3>
1232
+ <div class="inside">
1233
+ <table id="dbem-location-data">
1234
+ <tr>
1235
+ <th><?php _e('Name:') ?>&nbsp;</th><td><input id="location-name" type="text" name="location_name" value="<?php echo $event['location_name']?>" /></td>
1236
+ <?php $gmap_is_active = get_option('dbem_gmap_is_active'); ?>
1237
+
1238
+ <?php if ($gmap_is_active) { ?>
1239
+ <td rowspan='6'>
1240
+ <div id='map-not-found' style='width: 400px; font-size: 140%; text-align: center; margin-top: 100px; display: hide'><p><?php _e('Map not found');?></p></div>
1241
+ <div id='event-map' style='width: 400px; height: 300px; background: green; display: hide; margin-right:8px'></div>
1242
+ </td>
1243
+ <?php } ; // end of IF_GMAP_ACTIVE?>
1244
+ </tr>
1245
+ <tr>
1246
+ <td colspan='2'>
1247
+ <p><?php _e('The name of the location where the event takes place. You can use the name of a venue, a square, etc','dbem') ?> </p>
1248
+ </td>
1249
+ </tr>
1250
+ <tr>
1251
+ <th><?php _e('Address:') ?>&nbsp;</th><td><input id="location-address" type="text" name="location_address" value="<?php echo $event['location_address']; ?>" /></td>
1252
+ </tr>
1253
+ <tr>
1254
+ <td colspan='2'>
1255
+ <p><?php _e('The address of the location where the event takes place. Example: 21, Dominick Street','dbem') ?> </p>
1256
+ </td>
1257
+ </tr>
1258
+ <tr>
1259
+ <th><?php _e('Town:') ?>&nbsp;</th><td> <input id="location-town" type="text" name="location_town" value="<?php echo $event['location_town']?>" /></td>
1260
+ </tr>
1261
+ <tr>
1262
+ <td colspan='2'>
1263
+ <p><?php _e('The town where the location is located. If you\'re using the Google Map integration and want to avoid geotagging ambiguities include the country in the town field. Example: Verona, Italy.', 'dbem') ?></p>
1264
+ </td>
1265
+ </tr>
1266
+ </table>
1267
+ </div>
1268
+ </div>
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+ <div id="event_notes" class="postbox">
1275
+ <h3><?php _e('Details','dbem'); ?></h3>
1276
+ <div class="inside">
1277
+ <textarea name="event_notes" rows="8" cols="60"><?php echo $event[$pref.'notes']; ?></textarea><br/>
1278
+ <?php _e('Details about the event', 'dbem') ?>
1279
+ </div>
1280
+ </div>
1281
+ </div>
1282
+ <p class="submit"><input type="submit" name="events_update" value="<?php _e('Submit Event','dbem'); ?> &raquo;" /></p>
1283
+ </div>
1284
+
1285
+ </div>
1286
+ </div>
1287
+ </form>
1288
+ <?php
1289
+ }
1290
+
1291
+ function dbem_validate_event($event) {
1292
+ // TODO decide which fields are required
1293
+ // Implement type check for dates, etc
1294
+ global $required_fields;
1295
+
1296
+ foreach ($required_fields as $field) {
1297
+ if ($event[$field] == "" ) {
1298
+ return $field.__(" is missing!", "dbem");
1299
+ }
1300
+ }
1301
+
1302
+ $event_year = substr($event['event_date'],0,4);
1303
+ $event_month = substr($event['event_date'],5,2);
1304
+ $event_day = substr($event['event_date'],8,2);
1305
+
1306
+ // if (!_dbem_is_date_valid($event['event_date'])) {
1307
+ // return __("invalid date!", "dbem");
1308
+ // }
1309
+ $time = $event['event_hh'].":".$event['event_mm'];
1310
+ $end_time = $event['event_end_hh'].":".$event['event_end_mm'];
1311
+ // TODO re-IMPLEMENT TIME VALIDATION
1312
+ // if ( !_dbem_is_time_valid($time) ) {
1313
+ // return __("invalid time","dbem");
1314
+ // }
1315
+ $use_event_end = get_option('dbem_use_event_end');
1316
+ if ($use_event_end && $event['event_date']." ".$time > $event['event_end_date']." ".$end_time)
1317
+ return __("end date before begin date", "dbem");
1318
+ return "OK";
1319
+
1320
+ }
1321
+
1322
+ function _dbem_is_date_valid($date) {
1323
+ $year = substr($date,0,4);
1324
+ $month = substr($date,5,2);
1325
+ $day = substr($date,8,2);
1326
+ return (checkdate($month, $day, $year));
1327
+ }
1328
+ function _dbem_is_time_valid($time) {
1329
+ $result = preg_match ("/([01]\d|2[0-3])(:[0-5]\d)/", $time);
1330
+
1331
+ return ($result);
1332
+ }
1333
+ // Enqueing jQuery script to make sure it's loaded
1334
+ function dbem_enque_scripts(){
1335
+ wp_enqueue_script( 'jquery' );
1336
+ // wp_enqueue_script('datepicker','/wp-content/plugins/events-manager/jquery-ui-datepicker/jquery-ui-personalized-1.6b.js', array('jquery') );
1337
+ }
1338
+ add_action ('template_redirect', 'dbem_enque_scripts');
1339
+
1340
+ function url_exists($url) {
1341
+
1342
+ if ((strpos($url, "http")) === false) $url = "http://" . $url;
1343
+ // FIXME ripristina la linea seguente e VEDI DI SISTEMARE!!!!
1344
+ // if (is_array(@get_headers($url))) {
1345
+ if (true)
1346
+ return true;
1347
+ else
1348
+ return false;
1349
+ }
1350
+
1351
+ // General script to make sure hidden fields are shown when containing data
1352
+ function dbem_admin_general_script(){ ?>
1353
+ <script src="<?php bloginfo('url');?>/wp-content/plugins/events-manager/dbem.js" type="text/javascript"></script>
1354
+ <script src="<?php bloginfo('url');?>/wp-content/plugins/events-manager/js/jquery-ui-datepicker/ui.datepicker.js" type="text/javascript"></script>
1355
+ <script src="<?php bloginfo('url');?>/wp-content/plugins/events-manager/js/timeentry/jquery.timeentry.js" type="text/javascript"></script>
1356
+ <?php
1357
+
1358
+ // Check if the locale is there and loads it
1359
+ $locale_code = substr(get_locale(), 0, 2);
1360
+
1361
+ $show24Hours = 'true';
1362
+ // Setting 12 hours format for those countries using it
1363
+ if(preg_match("/en|sk|zh|us|uk/",$locale_code))
1364
+ $show24Hours = 'false';
1365
+
1366
+
1367
+ $locale_file = get_bloginfo('url')."/wp-content/plugins/events-manager/js/jquery-ui-datepicker/i18n/ui.datepicker-$locale_code.js";
1368
+ if(url_exists($locale_file)) { ?>
1369
+ <script src="<?php bloginfo('url');?>/wp-content/plugins/events-manager/js/jquery-ui-datepicker/i18n/ui.datepicker-<?php echo $locale_code;?>.js" type="text/javascript"></script>
1370
+ <?php } ?>
1371
+
1372
+
1373
+ <style type='text/css' media='all'>
1374
+ @import "<?php bloginfo('url');?>/wp-content/plugins/events-manager/js/jquery-ui-datepicker/ui.datepicker.css";
1375
+ </style>
1376
+ <script type="text/javascript">
1377
+ //<![CDATA[
1378
+ // TODO: make more general, to support also latitude and longitude (when added)
1379
+ $j=jQuery.noConflict();
1380
+
1381
+ function updateIntervalDescriptor () {
1382
+ $j(".interval-desc").hide();
1383
+ var number = "-plural";
1384
+ if ($j('input#recurrence-interval').val() == 1 || $j('input#recurrence-interval').val() == "")
1385
+ number = "-singular"
1386
+ var descriptor = "span#interval-"+$j("select#recurrence-frequency").val()+number;
1387
+ $j(descriptor).show();
1388
+ }
1389
+ function updateIntervalSelectors () {
1390
+ $j('p.alternate-selector').hide();
1391
+ $j('p#'+ $j('select#recurrence-frequency').val() + "-selector").show();
1392
+ //$j('p.recurrence-tip').hide();
1393
+ //$j('p#'+ $j(this).val() + "-tip").show();
1394
+ }
1395
+ function updateShowHideRecurrence () {
1396
+ if($j('input#event-recurrence').attr("checked")) {
1397
+ $j("#event_recurrence_pattern").fadeIn();
1398
+ $j("input#localised-end-date").fadeIn();
1399
+ $j("#event-date-explanation").hide();
1400
+ $j("#recurrence-dates-explanation").show();
1401
+ $j("h3#recurrence-dates-title").show();
1402
+ $j("h3#event-date-title").hide();
1403
+ } else {
1404
+ $j("#event_recurrence_pattern").hide();
1405
+ $j("input#localised-end-date").hide();
1406
+ $j("#recurrence-dates-explanation").hide();
1407
+ $j("#event-date-explanation").show();
1408
+ $j("h3#recurrence-dates-title").hide();
1409
+ $j("h3#event-date-title").show();
1410
+ }
1411
+ }
1412
+
1413
+ function updateShowHideRsvp () {
1414
+ if($j('input#rsvp-checkbox').attr("checked")) {
1415
+ $j("div#rsvp-data").fadeIn();
1416
+ } else {
1417
+ $j("div#rsvp-data").hide();
1418
+ }
1419
+ }
1420
+
1421
+ $j(document).ready( function() {
1422
+ locale_format = "ciao";
1423
+
1424
+ $j("#recurrence-dates-explanation").hide();
1425
+ $j("#localised-date").show();
1426
+
1427
+ $j("#date-to-submit").hide();
1428
+ $j("#end-date-to-submit").hide();
1429
+ $j("#localised-date").datepicker($j.extend({},
1430
+ ($j.datepicker.regional["it"],
1431
+ {altField: "#date-to-submit",
1432
+ altFormat: "yy-mm-dd"})));
1433
+ $j("#localised-end-date").datepicker($j.extend({},
1434
+ ($j.datepicker.regional["it"],
1435
+ {altField: "#end-date-to-submit",
1436
+ altFormat: "yy-mm-dd"})));
1437
+
1438
+
1439
+
1440
+
1441
+
1442
+
1443
+ $j("#start-time").timeEntry({spinnerImage: '', show24Hours: <?php echo $show24Hours;?> });
1444
+ $j("#end-time").timeEntry({spinnerImage: '', show24Hours: <?php echo $show24Hours;?>});
1445
+
1446
+
1447
+
1448
+
1449
+
1450
+ $j('input.select-all').change(function(){
1451
+ if($j(this).is(':checked'))
1452
+ $j('input.row-selector').attr('checked', true);
1453
+ else
1454
+ $j('input.row-selector').attr('checked', false);
1455
+ });
1456
+ // TODO: NOT WORKING FOR SOME REASON, val() gives me 2 instead of 'smtp'...
1457
+ // console.log($j('select[name:dbem_rsvp_mail_send_method]').val());
1458
+ // if ($j('select[name:dbem_rsvp_mail_send_method]').val() != "smtp") {
1459
+ // $j('tr#dbem_smtp_host_row').hide();
1460
+ // $j('tr#dbem_rsvp_mail_SMTPAuth_row').hide();
1461
+ // $j('tr#dbem_smtp_username_row').hide();
1462
+ // $j('tr#dbem_smtp_password_row').hide();
1463
+ // }
1464
+ //
1465
+ // $j('select[name:dbem_rsvp_mail_send_method]').change(function() {
1466
+ // console.log($j(this).val());
1467
+ // if($j(this).val() == "smtp") {
1468
+ // $j('tr#dbem_smtp_host_row').show();
1469
+ // $j('tr#dbem_rsvp_mail_SMTPAuth_row').show();
1470
+ // $j('tr#dbem_smtp_username_row').show();
1471
+ // $j('tr#dbem_smtp_password_row').show();
1472
+ // } else {
1473
+ // $j('tr#dbem_smtp_host_row').hide();
1474
+ // $j('tr#dbem_rsvp_mail_SMTPAuth_row').hide();
1475
+ // $j('tr#dbem_smtp_username_row').hide();
1476
+ // $j('tr#dbem_smtp_password_row').hide();
1477
+ // }
1478
+
1479
+ //});
1480
+ updateIntervalDescriptor();
1481
+ updateIntervalSelectors();
1482
+ updateShowHideRecurrence();
1483
+ updateShowHideRsvp();
1484
+ $j('input#event-recurrence').change(updateShowHideRecurrence);
1485
+ $j('input#rsvp-checkbox').change(updateShowHideRsvp);
1486
+ // recurrency elements
1487
+ $j('input#recurrence-interval').keyup(updateIntervalDescriptor);
1488
+ $j('select#recurrence-frequency').change(updateIntervalDescriptor);
1489
+ $j('select#recurrence-frequency').change(updateIntervalSelectors);
1490
+
1491
+ // hiding or showing notes according to their content
1492
+ jQuery('.postbox h3').prepend('<a class="togbox">+</a> ');
1493
+ // if(jQuery("textarea[@name=event_notes]").val()!="") {
1494
+ // jQuery("textarea[@name=event_notes]").parent().parent().removeClass('closed');
1495
+ // }
1496
+ jQuery('#event_notes h3').click( function() {
1497
+ jQuery(jQuery(this).parent().get(0)).toggleClass('closed');
1498
+ });
1499
+ });
1500
+ //]]>
1501
+ </script>
1502
+
1503
+ <?php
1504
+ }
1505
+ add_action ('admin_head', 'dbem_admin_general_script');
1506
+
1507
+
1508
+
1509
+
1510
+ function dbem_admin_map_script() {
1511
+ if ((isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '') || (isset($_REQUEST['page']) && $_REQUEST['page'] == 'locations') || (isset($_REQUEST['page']) && $_REQUEST['page'] == 'new_event') || (isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit_recurrence') ) {
1512
+ if (!(isset($_REQUEST['action']) && $_REQUEST['action'] == 'dbem_delete')) {
1513
+ // single event page
1514
+
1515
+
1516
+ $event_ID=$_REQUEST['event_id'];
1517
+ $event = dbem_get_event($event_ID);
1518
+
1519
+ if ($event['location_town'] != '' || (isset($_REQUEST['page']) && $_REQUEST['page'] = 'locations')) {
1520
+ $gmap_key = get_option('dbem_gmap_key');
1521
+ if($event['location_address'] != "") {
1522
+ $search_key = $event['location_address'].", ".$event['location_town'];
1523
+ } else {
1524
+ $search_key = $event['location_name'].", ".$event['location_town'];
1525
+ }
1526
+
1527
+ ?>
1528
+ <style type="text/css">
1529
+ /* div#location_town, div#location_address, div#location_name {
1530
+ width: 480px;
1531
+ }
1532
+ table.form-table {
1533
+ width: 50%;
1534
+ } */
1535
+ </style>
1536
+ <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=<?php echo $gmap_key;?>" type="text/javascript"></script>
1537
+ <script type="text/javascript">
1538
+ //<![CDATA[
1539
+ $j=jQuery.noConflict();
1540
+
1541
+ function loadMap(location, town, address) {
1542
+ if (GBrowserIsCompatible()) {
1543
+ var map = new GMap2(document.getElementById("event-map"));
1544
+ // map.addControl(new GScaleControl());
1545
+ //map.setCenter(new GLatLng(37.4419, -122.1419), 13);
1546
+ var geocoder = new GClientGeocoder();
1547
+ if (address !="") {
1548
+ searchKey = address + ", " + town;
1549
+ } else {
1550
+ searchKey = location + ", " + town;
1551
+ }
1552
+
1553
+ var search = "<?php echo $search_key ?>" ;
1554
+ geocoder.getLatLng(
1555
+ searchKey,
1556
+ function(point) {
1557
+ if (!point) {
1558
+ $j("#event-map").hide();
1559
+ $j('#map-not-found').show();
1560
+ } else {
1561
+ mapCenter= new GLatLng(point.lat()+0.01, point.lng()+0.005);
1562
+ map.setCenter(mapCenter, 13);
1563
+ var marker = new GMarker(point);
1564
+ map.addOverlay(marker);
1565
+ marker.openInfoWindowHtml('<strong>' + location +'</strong><p>' + address + '</p><p>' + town + '</p>');
1566
+ $j('input#location-latitude').val(point.y);
1567
+ $j('input#location-longitude').val(point.x);
1568
+ $j("#event-map").show();
1569
+ $j('#map-not-found').hide();
1570
+ }
1571
+ }
1572
+ );
1573
+ // map.addControl(new GSmallMapControl());
1574
+ // map.addControl(new GMapTypeControl());
1575
+
1576
+ }
1577
+ }
1578
+
1579
+ $j(document).ready(function() {
1580
+ eventLocation = $j("input#location-name").val();
1581
+ eventTown = $j("input#location-town").val();
1582
+ eventAddress = $j("input#location-address").val();
1583
+
1584
+ loadMap(eventLocation, eventTown, eventAddress);
1585
+
1586
+ $j("input#location-name").blur(function(){
1587
+ newEventLocation = $j("input#location-name").val();
1588
+ if (newEventLocation !=eventLocation) {
1589
+ loadMap(newEventLocation, eventTown, eventAddress);
1590
+ eventLocation = newEventLocation;
1591
+
1592
+ }
1593
+ });
1594
+ $j("input#location-town").blur(function(){
1595
+ newEventTown = $j("input#location-town").val();
1596
+ if (newEventTown !=eventTown) {
1597
+ loadMap(eventLocation, newEventTown, eventAddress);
1598
+ eventTown = newEventTown;
1599
+ }
1600
+ });
1601
+ $j("input#location-address").blur(function(){
1602
+ newEventAddress = $j("input#location-address").val();
1603
+ if (newEventAddress != eventAddress) {
1604
+ loadMap(eventLocation, eventTown, newEventAddress);
1605
+ eventAddress = newEventAddress;
1606
+ }
1607
+ });
1608
+
1609
+
1610
+
1611
+ });
1612
+ $j(document).unload(function() {
1613
+ GUnload();
1614
+ });
1615
+ //]]>
1616
+ </script>
1617
+ <?php
1618
+ }
1619
+ }
1620
+ }
1621
+ }
1622
+ $gmap_is_active = get_option('dbem_gmap_is_active');
1623
+ if ($gmap_is_active) {
1624
+ add_action ('admin_head', 'dbem_admin_map_script');
1625
+
1626
+ }
1627
+
1628
+ // Script to validate map options
1629
+ function dbem_admin_options_script() {
1630
+ if (isset($_REQUEST['page']) && $_REQUEST['page'] == 'events-manager-options') {
1631
+ ?>
1632
+ <script type="text/javascript">
1633
+ //<![CDATA[
1634
+ $j=jQuery.noConflict();
1635
+
1636
+ $j(document).ready(function() {
1637
+
1638
+ // users cannot enable Google Maps without an api key
1639
+ function verifyOptionsForm(){
1640
+ var gmap_is_active = $j("input[@name=dbem_gmap_is_active]:checked").val();
1641
+ var gmap_key = $j("input[@name=dbem_gmap_key]").val();
1642
+ if(gmap_is_active == '1' && (gmap_key == '')){
1643
+ alert("<?php _e('You cannot enable Google Maps integration without setting an appropriate API key.');?>");
1644
+ $j("input[@name='dbem_gmap_is_active']:nth(1)").attr("checked","checked");
1645
+
1646
+ return false;
1647
+ } else {
1648
+ return true;
1649
+ }
1650
+ }
1651
+
1652
+ $j('#dbem_options_form').bind("submit", verifyOptionsForm);
1653
+
1654
+
1655
+ });
1656
+
1657
+
1658
+ //]]>
1659
+ </script>
1660
+
1661
+ <?php
1662
+
1663
+ }
1664
+
1665
+ }
1666
+ add_action ('admin_head', 'dbem_admin_options_script');
1667
+
1668
+ function dbem_rss_link($justurl=0, $echo=1, $text="RSS") {
1669
+ if(strpos($justurl, "=")) {
1670
+ // allows the use of arguments without breaking the legacy code
1671
+ $defaults = array(
1672
+ 'justurl' => 0,
1673
+ 'echo' => 1,
1674
+ 'text' => 'RSS',
1675
+ );
1676
+
1677
+ $r = wp_parse_args( $justurl, $defaults );
1678
+ extract( $r, EXTR_SKIP );
1679
+ $justurl = $r['justurl'];
1680
+ $echo = $r['echo'];
1681
+ $text = $r['text'];
1682
+ }
1683
+ if ($text == '')
1684
+ $text = "RSS";
1685
+ $rss_title = get_option('dbem_events_page_title');
1686
+ $url = get_bloginfo('url')."/?dbem_rss=main";
1687
+ $link = "<a href='$url'>$text</a>";
1688
+
1689
+ if ($justurl)
1690
+ $result = $url;
1691
+ else
1692
+ $result = $link;
1693
+ if($echo)
1694
+ echo $result;
1695
+ else
1696
+ return $result;
1697
+ }
1698
+
1699
+ function dbem_rss_link_shortcode($atts) {
1700
+ extract(shortcode_atts(array(
1701
+ 'justurl' => 0,
1702
+ 'text' => 'RSS',
1703
+ ), $atts));
1704
+ $result = dbem_rss_link("justurl=$justurl&echo=0&text=$text") ;
1705
+ return $result;
1706
+ }
1707
+ add_shortcode('events_rss_link', 'dbem_rss_link_shortcode');
1708
+
1709
+
1710
+
1711
+ function dbem_rss() {
1712
+ if (isset($_REQUEST['dbem_rss']) && $_REQUEST['dbem_rss'] == 'main') {
1713
+ header("Content-type: text/xml");
1714
+ echo "<?xml version='1.0'?>\n";
1715
+
1716
+ $events_page_id = get_option('dbem_events_page');
1717
+ $events_page_link = get_permalink($events_page_id);
1718
+ if (stristr($events_page_link, "?"))
1719
+ $joiner = "&amp;";
1720
+ else
1721
+ $joiner = "?";
1722
+
1723
+
1724
+ ?>
1725
+ <rss version="2.0">
1726
+ <channel>
1727
+ <title><?php echo get_option('dbem_rss_main_title');?></title>
1728
+ <link><?php echo $events_page_link; ?></link>
1729
+ <description><?php echo get_option('dbem_rss_main_description');?></description>
1730
+ <docs>http://blogs.law.harvard.edu/tech/rss</docs>
1731
+ <generator>Weblog Editor 2.0</generator>
1732
+ <?php
1733
+ $title_format = get_option('dbem_rss_title_format');
1734
+ $description_format = str_replace(">","&gt;",str_replace("<","&lt;",get_option('dbem_rss_description_format')));
1735
+ $events = dbem_get_events(5);
1736
+ foreach ($events as $event) {
1737
+ $title = dbem_replace_placeholders($title_format, $event, "rss");
1738
+ $description = dbem_replace_placeholders($description_format, $event, "rss");
1739
+ echo "<item>";
1740
+ echo "<title>$title</title>\n";
1741
+ echo "<link>$events_page_link".$joiner."event_id=$event->event_id</link>\n ";
1742
+ echo "<description>$description </description>\n";
1743
+ echo "</item>";
1744
+ }
1745
+ ?>
1746
+
1747
+ </channel>
1748
+ </rss>
1749
+ </code>
1750
+
1751
+ <?php
1752
+ die();
1753
+ }
1754
+ }
1755
+ add_action('init','dbem_rss');
1756
+ function substitute_rss($data) {
1757
+ if (isset($_REQUEST['event_id']))
1758
+ return get_bloginfo('url')."/?dbem_rss=main";
1759
+ else
1760
+ return $data;
1761
+ }
1762
+ function dbem_general_css() {
1763
+ $base_url = get_bloginfo('url');
1764
+ echo "<link rel='stylesheet' href='$base_url/wp-content/plugins/events-manager/events_manager.css' type='text/css'/>";
1765
+
1766
+ }
1767
+ add_action('wp_head','dbem_general_css');
1768
+ add_action('admin_head','dbem_general_css');
1769
+ //add_filter('feed_link','substitute_rss')
1770
+
1771
+ // TODO roba da mettere nell'ordine giusto
1772
+ function dbem_delete_event($event_id) {
1773
+ global $wpdb;
1774
+ $table_name = $wpdb->prefix.EVENTS_TBNAME;
1775
+ $sql = "DELETE FROM $table_name WHERE event_id = '$event_id';";
1776
+ $wpdb->query($sql);
1777
+
1778
+ }
1779
+ add_filter('favorite_actions', 'dbem_favorite_menu');
1780
+
1781
+ function dbem_favorite_menu($actions) {
1782
+ // add quick link to our favorite plugin
1783
+ $actions['admin.php?page=new_event'] = array(__('Add an event', 'dbem'), MIN_CAPABILITY);
1784
+ return $actions;
1785
+ }
1786
+
1787
+ ////////////////////////////////////
1788
+ // WP 2.7 options registration
1789
+ function dbem_options_register() {
1790
+ $options = array(
1791
+ 'dbem_use_event_end',
1792
+ 'dbem_event_list_item_format',
1793
+ 'dbem_event_page_title_format',
1794
+ 'dbem_single_event_format',
1795
+ 'dbem_list_events_page',
1796
+ 'dbem_events_page_title',
1797
+ 'dbem_no_events_message',
1798
+ 'dbem_location_page_title_format','dbem_location_baloon_format',
1799
+ 'dbem_single_location_format',
1800
+ 'dbem_location_event_list_item_format',
1801
+ 'dbem_location_no_events_message',
1802
+ 'dbem_gmap_is_active',
1803
+ 'dbem_rss_main_title',
1804
+ 'dbem_rss_main_description',
1805
+ 'dbem_rss_title_format',
1806
+ 'dbem_rss_description_format',
1807
+ 'dbem_gmap_key',
1808
+ 'dbem_map_text_format',
1809
+ 'dbem_rsvp_mail_notify_is_active',
1810
+ 'dbem_contactperson_email_body',
1811
+ 'dbem_respondent_email_body',
1812
+ 'dbem_mail_sender_name',
1813
+ 'dbem_smtp_username',
1814
+ 'dbem_smtp_password',
1815
+ 'dbem_default_contact_person',
1816
+ 'dbem_mail_sender_address',
1817
+ 'dbem_mail_receiver_address',
1818
+ 'dbem_smtp_host',
1819
+ 'dbem_rsvp_mail_send_method',
1820
+ 'dbem_rsvp_mail_port',
1821
+ 'dbem_rsvp_mail_SMTPAuth',
1822
+ 'dbem_image_max_width',
1823
+ 'dbem_image_max_height',
1824
+ 'dbem_image_max_size',
1825
+ );
1826
+ foreach($options as $opt) {
1827
+ register_setting('dbem-options',$opt,'');
1828
+ }
1829
+
1830
+ }
1831
+ add_action( 'admin_init', 'dbem_options_register' );
1832
+ ?>
dbem_global_map.js ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $j=jQuery.noConflict();
2
+ console.log("eventful: " + eventful + " scope " + scope);
3
+
4
+ $j(document.body).unload(function() {
5
+ if (GBrowserIsCompatible()) {
6
+ GUnload();
7
+ }
8
+ });
9
+
10
+
11
+ $j(document).ready(function() {
12
+ loadMapScript(GMapsKey);
13
+ });
14
+
15
+
16
+
17
+ function loadGMap() {
18
+ if (GBrowserIsCompatible()) {
19
+
20
+ var locations;
21
+ $j.getJSON(document.URL,{ajax: 'true', query:'GlobalMapData', eventful:eventful}, function(data){
22
+ locations = data.locations;
23
+ var latitudes = new Array();
24
+ var longitudes = new Array();
25
+ var max_latitude = -500.1;
26
+ var min_latitude = 500.1;
27
+ var max_longitude = -500.1;
28
+ var min_longitude = 500.1;
29
+
30
+ map = new GMap2(document.getElementById("dbem_global_map"));
31
+ map.setCenter(new GLatLng(45.4213477,10.952397), 3);
32
+
33
+ $j.each(locations, function(i, item){
34
+ latitudes.push(item.location_latitude);
35
+ longitudes.push(item.location_longitude);
36
+ if (parseFloat(item.location_latitude) > max_latitude)
37
+ max_latitude = parseFloat(item.location_latitude);
38
+ if (parseFloat(item.location_latitude) < min_latitude)
39
+ min_latitude = parseFloat(item.location_latitude);
40
+ if (parseFloat(item.location_longitude) > max_longitude)
41
+ max_longitude = parseFloat(item.location_longitude);
42
+ if (parseFloat(item.location_longitude) < min_longitude)
43
+ min_longitude = parseFloat(item.location_longitude);
44
+
45
+
46
+ });
47
+
48
+ //console.log("Latitudes: " + latitudes + " MAX: " + max_latitude + " MIN: " + min_latitude);
49
+ //console.log("Longitudes: " + longitudes + " MAX: " + max_longitude + " MIN: " + min_longitude);
50
+
51
+ center_lat = min_latitude + (max_latitude - min_latitude)/2;
52
+ center_lon = min_longitude + (max_longitude - min_longitude)/2;
53
+ //console.log("center: " + center_lat + " - " + center_lon) + min_longitude;
54
+
55
+ lat_interval = max_latitude - min_latitude;
56
+
57
+ //vertical compensation to fit in the markers
58
+ vertical_compensation = lat_interval * 0.1;
59
+
60
+ var locationsBound = new GLatLngBounds(new GLatLng(max_latitude + vertical_compensation,min_longitude),new GLatLng(min_latitude,max_longitude) );
61
+ //console.log(locationsBound);
62
+ var locationsZoom = map.getBoundsZoomLevel(locationsBound);
63
+ map.setCenter(new GLatLng(center_lat + vertical_compensation,center_lon), locationsZoom);
64
+ var letters = new Array('A','B','C','D','E','F','G','H');
65
+ var customIcon = new GIcon(G_DEFAULT_ICON);
66
+
67
+ $j.each(locations, function(i, item){
68
+ var letter = letters[i];
69
+
70
+ customIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
71
+
72
+ markerOption = { icon:customIcon };
73
+ var point = new GLatLng(parseFloat(item.location_latitude), parseFloat(item.location_longitude));
74
+ var marker = new GMarker(point, markerOption);
75
+ map.addOverlay(marker);
76
+ var li_element = "<li id='location-"+item.location_id+"' style='list-style-type: upper-alpha'><a >"+ item.location_name+"</a></li>";
77
+ $j('ol#dbem_locations_list').append(li_element);
78
+ $j('li#location-'+item.location_id+' a').click(function(){
79
+ displayLocationInfo(marker, item);
80
+ });
81
+ GEvent.addListener(marker, "click", function() {
82
+ displayLocationInfo(marker, item);
83
+
84
+ });
85
+
86
+
87
+ });
88
+
89
+
90
+
91
+ });
92
+
93
+
94
+ }
95
+ }
96
+
97
+
98
+ function loadMapScript(key) {
99
+ var script = document.createElement("script");
100
+ script.setAttribute("src", "http://maps.google.com/maps?file=api&v=2.x&key=" + key + "&c&async=2&callback=loadGMap");
101
+ script.setAttribute("type", "text/javascript");
102
+ document.documentElement.firstChild.appendChild(script);
103
+ }
104
+
105
+ function displayLocationInfo(marker, location) {
106
+ var location_infos = "<strong>"+ location.location_name +"</strong><br/>" + location.location_address + ", " + location.location_town + "<br/><small><a href='" + events_page + "&location_id=" + location.location_id + "'>Details<a>";
107
+ window.map.openInfoWindowHtml(marker.getLatLng(),location.location_baloon, {pixelOffset: new GSize(0,-32)});
108
+ }
dbem_locations.php ADDED
@@ -0,0 +1,708 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $feedback_message = "";
3
+
4
+ $location_required_fields = array("location_name" => __('The location name', 'dbem'), "location_address" => __('The location address', 'dbem'), "location_town" => __('The location town', 'dbem'));
5
+
6
+
7
+ add_action('init', 'dbem_intercept_locations_actions');
8
+ function dbem_intercept_locations_actions() {
9
+ if(isset($_GET['page']) && $_GET['page'] == "locations") {
10
+ if(isset($_GET['doaction2']) && $_GET['doaction2'] == "Delete") {
11
+ if(isset($_GET['action2']) && $_GET['action2'] == "delete") {
12
+ $locations = $_GET['locations'];
13
+ foreach($locations as $location_ID) {
14
+ dbem_delete_location($location_ID);
15
+ }
16
+ }
17
+ }
18
+ }
19
+ }
20
+
21
+ function dbem_locations_page() {
22
+
23
+ if(isset($_GET['action']) && $_GET['action'] == "edit") {
24
+ // edit location
25
+ $location_id = $_GET['location_ID'];
26
+ $location = dbem_get_location($location_id);
27
+ dbem_locations_edit_layout($location);
28
+ } else {
29
+ if(isset($_POST['action']) && $_POST['action'] == "editedlocation") {
30
+
31
+ // location update required
32
+ $location = array();
33
+ $location['location_id'] = $_POST['location_ID'];
34
+ $location['location_name'] = $_POST['location_name'];
35
+ $location['location_address'] = $_POST['location_address'];
36
+ $location['location_town'] = $_POST['location_town'];
37
+ $location['location_latitude'] = $_POST['location_latitude'];
38
+ $location['location_longitude'] = $_POST['location_longitude'];
39
+ $location['location_description'] = $_POST['location_description'];
40
+
41
+ if(empty($location['location_latitude'])) {
42
+ $location['location_latitude'] = 0;
43
+ $location['location_longitude'] = 0;
44
+ }
45
+
46
+ $validation_result = dbem_validate_location($location);
47
+ if ($validation_result == "OK") {
48
+
49
+ dbem_update_location($location);
50
+
51
+ if ($_FILES['location_image']['size'] > 0 )
52
+ dbem_upload_location_picture($location);
53
+ $message = __('The location has been updated.', 'dbem');
54
+
55
+ $locations = dbem_get_locations();
56
+ dbem_locations_table_layout($locations, $message);
57
+ } else {
58
+ $message = $validation_result;
59
+ dbem_locations_edit_layout($location, $message);
60
+ }
61
+ } elseif(isset($_POST['action']) && $_POST['action'] == "addlocation") {
62
+ $location = array();
63
+ $location['location_name'] = $_POST['location_name'];
64
+ $location['location_address'] = $_POST['location_address'];
65
+ $location['location_town'] = $_POST['location_town'];
66
+ $location['location_latitude'] = $_POST['location_latitude'];
67
+ $location['location_longitude'] = $_POST['location_longitude'];
68
+ $location['location_description'] = $_POST['location_description'];
69
+ $validation_result = dbem_validate_location($location);
70
+ if ($validation_result == "OK") {
71
+ $new_location = dbem_insert_location($location);
72
+ // uploading the image
73
+
74
+ if ($_FILES['location_image']['size'] > 0 ) {
75
+ dbem_upload_location_picture($new_location);
76
+ }
77
+
78
+
79
+
80
+
81
+
82
+
83
+ // -------------
84
+
85
+ //RESETME $message = __('The location has been added.', 'dbem');
86
+ $locations = dbem_get_locations();
87
+ dbem_locations_table_layout($locations, null,$message);
88
+ } else {
89
+ $message = $validation_result;
90
+ $locations = dbem_get_locations();
91
+
92
+ dbem_locations_table_layout($locations, $location, $message);
93
+ }
94
+
95
+
96
+
97
+ } else {
98
+ // no action, just a locations list
99
+ $locations = dbem_get_locations();
100
+ dbem_locations_table_layout($locations, $message);
101
+ }
102
+ }
103
+ }
104
+
105
+ function dbem_locations_edit_layout($location, $message = "") {
106
+ $layout = "
107
+ <div class='wrap'>
108
+ <div id='icon-edit' class='icon32'>
109
+ <br/>
110
+ </div>
111
+
112
+ <h2>".__('Edit location', 'dbem')."</h2>";
113
+
114
+ if($message != "") {
115
+ $layout .= "
116
+ <div id='message' class='updated fade below-h2' style='background-color: rgb(255, 251, 204);'>
117
+ <p>$message</p>
118
+ </div>";
119
+ }
120
+ $layout .= "
121
+ <div id='ajax-response'></div>
122
+
123
+ <form enctype='multipart/form-data' name='editcat' id='editcat' method='post' action='admin.php?page=locations' class='validate'>
124
+ <input type='hidden' name='action' value='editedlocation' />
125
+ <input type='hidden' name='location_ID' value='".$location['location_id']."'/>";
126
+
127
+ $layout .= "<table class='form-table'>
128
+ <tr class='form-field form-required'>
129
+ <th scope='row' valign='top'><label for='location_name'>".__('Location name', 'dbem')."</label></th>
130
+ <td><input name='location_name' id='location-name' type='text' value='".$location['location_name']."' size='40' /><br />
131
+ ".__('The name of the location', 'dbem')."</td>
132
+ </tr>
133
+
134
+ <tr class='form-field'>
135
+ <th scope='row' valign='top'><label for='location_address'>".__('Location address', 'dbem')."</label></th>
136
+ <td><input name='location_address' id='location-address' type='text' value='".$location['location_address']."' size='40' /><br />
137
+ ".__('The address of the location', 'dbem').".</td>
138
+
139
+ </tr>
140
+
141
+ <tr class='form-field'>
142
+ <th scope='row' valign='top'> <label for='location_town'>".__('Location town', 'dbem')."</label></th>
143
+ <td><input name='location_town' id='location-town' type='text' value='".$location['location_town']."' size='40' /><br />
144
+ ".__('The town where the location is located', 'dbem').".</td>
145
+
146
+ </tr>
147
+
148
+ <tr style='display:none;'>
149
+ <td>Coordinates</td>
150
+ <td><input id='location-latitude' name='location_latitude' id='location_latitude' type='text' value='".$location['location_latitude']."' size='15' />
151
+ <input id='location-longitude' name='location_longitude' id='location_longitude' type='text' value='".$location['location_longitude']."' size='15' /></td>
152
+ </tr>\n ";
153
+ $gmap_is_active = get_option('dbem_gmap_is_active');
154
+ if ($gmap_is_active) {
155
+ $layout .= "
156
+
157
+ <tr>
158
+ <th scope='row' valign='top'><label for='location_map'>".__('Location map', 'dbem')."</label></th>
159
+ <td>
160
+ <div id='map-not-found' style='width: 450px; font-size: 140%; text-align: center; margin-top: 100px; display: hide'><p>".__('Map not found')."</p></div>
161
+ <div id='event-map' style='width: 450px; height: 300px; background: green; display: hide; margin-right:8px'></div></td></tr>";
162
+ }
163
+ $layout .= "
164
+ <tr class='form-field'>
165
+ <th scope='row' valign='top'><label for='location_description'>".__('Location description', 'dbem')."</label></th>
166
+ <td><textarea name='location_description' id='location_description' rows='5' cols='50' style='width: 97%;'>".$location['location_description']."</textarea><br />
167
+ ".__('A description of the Location. You may include any kind of info here.', 'dbem')."</td>
168
+
169
+ </tr>
170
+ <tr class='form-field'>
171
+ <th scope='row' valign='top'><label for='location_picture'>".__('Location image', 'dbem')."</label></th>
172
+ <td>";
173
+ if ($location['location_image_url'] != '')
174
+ $layout .= "<img src='".$location['location_image_url']."' alt='".$location['location_name']."'/>";
175
+ else
176
+ $layout .= __('No image uploaded for this location yet', 'debm');
177
+
178
+ $layout .= "</td>
179
+
180
+ </tr>
181
+ <tr>
182
+ <th scope='row' valign='top'><label for='location_image'>".__('Upload/change picture', 'dbem')."</label></th>
183
+ <td><input id='location-image' name='location_image' id='location_image' type='file' size='40' /></td>
184
+ </tr>\n
185
+ </table>
186
+ <p class='submit'><input type='submit' class='button-primary' name='submit' value='".__('Update location', 'dbem')."' /></p>
187
+ </form>
188
+
189
+
190
+ </div>
191
+
192
+ ";
193
+ echo $layout;
194
+ }
195
+
196
+ function dbem_locations_table_layout($locations, $new_location, $message = "") {
197
+ $destination = get_bloginfo('url')."/wp-admin/admin.php";
198
+ $table = "
199
+ <div class='wrap nosubsub'>\n
200
+ <div id='icon-edit' class='icon32'>
201
+ <br/>
202
+ </div>
203
+ <h2>".__('Locations', 'dbem')."</h2>\n ";
204
+
205
+ if($message != "") {
206
+ $table .= "
207
+ <div id='message' class='updated fade below-h2' style='background-color: rgb(255, 251, 204);'>
208
+ <p>$message</p>
209
+ </div>";
210
+ }
211
+ $table .= "
212
+ <div id='col-container'>\n
213
+ <div id='col-right'>\n
214
+ <div class='col-wrap'>\n
215
+ <form id='bookings-filter' method='get' action='$destination'>\n
216
+ <input type='hidden' name='page' value='locations'/>\n
217
+ <input type='hidden' name='action' value='edit_location'/>\n
218
+ <input type='hidden' name='event_id' value='$event_id'/>\n";
219
+
220
+ if (count($locations)>0) {
221
+ $table .= "<table class='widefat'>\n
222
+ <thead>\n
223
+ <tr>\n
224
+ <th class='manage-column column-cb check-column' scope='col'><input type='checkbox' class='select-all' value='1'/></th>\n
225
+ <th>".__('Name', 'dbem')."</th>\n
226
+ <th>".__('Address', 'dbem')."</th>\n
227
+ <th>".__('Town', 'dbem')."</th>\n
228
+ </tr>\n
229
+ </thead>\n
230
+ <tfoot>\n
231
+ <tr>\n
232
+ <th class='manage-column column-cb check-column' scope='col'><input type='checkbox' class='select-all' value='1'/></th>\n
233
+ <th>".__('Name', 'dbem')."</th>\n
234
+ <th>".__('Address', 'dbem')."</th>\n
235
+ <th>".__('Town', 'dbem')."</th>\n
236
+ </tr>\n
237
+ </tfoot>\n
238
+ <tbody>\n";
239
+ foreach ($locations as $this_location) {
240
+ $table .= "
241
+ <tr>\n
242
+ <td><input type='checkbox' class ='row-selector' value='".$this_location['location_id']."' name='locations[]'/></td>\n
243
+ <td><a href='".get_bloginfo('url')."/wp-admin/admin.php?page=locations&amp;action=edit&amp;location_ID=".$this_location['location_id']."'>".$this_location['location_name']."</a></td>\n
244
+ <td>".$this_location['location_address']."</td>\n
245
+ <td>".$this_location['location_town']."</td>\n
246
+ </tr>\n";
247
+ }
248
+ $table .= "
249
+ </tbody>\n
250
+
251
+ </table>\n
252
+
253
+ <div class='tablenav'>\n
254
+ <div class='alignleft actions'>\n
255
+ <input type='hidden' name='action2' value='delete'/>
256
+ <input class='button-secondary action' type='submit' name='doaction2' value='Delete'/>\n
257
+ <br class='clear'/>\n
258
+ </div>\n
259
+ <br class='clear'/>\n
260
+ </div>\n";
261
+ } else {
262
+ $table .= "<p>".__('No venues have been inserted yet!', 'dbem');
263
+ }
264
+ $table .= "
265
+ </form>\n
266
+ </div>\n
267
+ </div> <?-- end col-right -->\n
268
+
269
+ <div id='col-left'>\n
270
+ <div class='col-wrap'>\n
271
+ <div class='form-wrap'>\n
272
+ <div id='ajax-response'/>
273
+ <h3>".__('Add location', 'dbem')."</h3>\n
274
+ <form enctype='multipart/form-data' name='addlocation' id='addlocation' method='post' action='admin.php?page=locations' class='add:the-list: validate'>\n
275
+
276
+ <input type='hidden' name='action' value='addlocation' />\n
277
+ <div class='form-field form-required'>\n
278
+ <label for='location_name'>".__('Location name', 'dbem')."</label>\n
279
+ <input id='location-name' name='location_name' id='location_name' type='text' value='".$new_location['location_name']."' size='40' />\n
280
+ <p>".__('The name of the location', 'dbem').".</p>\n
281
+ </div>\n
282
+
283
+ <div class='form-field'>\n
284
+ <label for='location_address'>".__('Location address', 'dbem')."</label>\n
285
+ <input id='location-address' name='location_address' id='location_address' type='text' value='".$new_location['location_address']."' size='40' />\n
286
+ <p>".__('The address of the location', 'dbem').".</p>\n
287
+ </div>\n
288
+
289
+ <div class='form-field '>\n
290
+ <label for='location_town'>".__('Location town', 'dbem')."</label>\n
291
+ <input id='location-town' name='location_town' id='location_town' type='text' value='".$new_location['location_town']."' size='40' />\n
292
+ <p>".__('The town of the location', 'dbem').".</p>\n
293
+ </div>\n
294
+
295
+ <div class='form-field' style='display:none;'>\n
296
+ <label for='location_latitude'>LAT</label>\n
297
+ <input id='location-latitude' name='location_latitude' type='text' value='".$new_location['location_latitude']."' size='40' />\n
298
+ </div>\n
299
+ <div class='form-field' style='display:none;'>\n
300
+ <label for='location_longitude'>LONG</label>\n
301
+ <input id='location-longitude' name='location_longitude' type='text' value='".$new_location['location_longitude']."' size='40' />\n
302
+ </div>\n
303
+
304
+ <div class='form-field'>\n
305
+ <label for='location_image'>".__('Location image', 'dbem')."</label>\n
306
+ <input id='location-image' name='location_image' id='location_image' type='file' size='35' />\n
307
+ <p>".__('Select an image to upload', 'dbem').".</p>\n
308
+ </div>\n";
309
+ $gmap_is_active = get_option('dbem_gmap_is_active');
310
+
311
+ if ($gmap_is_active) {
312
+ $table .= "<div id='map-not-found' style='width: 450px; float: right; font-size: 140%; text-align: center; margin-top: 100px; display: hide'><p>".__('Map not found')."</p></div>";
313
+ $table .= "<div id='event-map' style='width: 450px; height: 300px; background: green; float: right; display: hide; margin-right:8px'></div>";
314
+ }
315
+ $table .= "
316
+ <div class='form-field'>\n
317
+ <label for='location_description'>".__('Location description', 'dbem')."</label>\n
318
+ <textarea name='location_description' id='location_description' rows='5' cols='40'>".$new_location['location_description']."</textarea>\n
319
+ <p>".__('A description of the location. You may include any kind of info here.', 'dbem')."</p>\n
320
+ </div>\n
321
+
322
+ <p class='submit'><input type='submit' class='button' name='submit' value='".__('Add location', 'dbem')."' /></p>\n
323
+ </form>\n
324
+
325
+ </div>\n
326
+ </div>\n
327
+ </div> <?-- end col-left -->\n
328
+ </div>\n
329
+ </div>\n";
330
+
331
+ echo $table;
332
+ }
333
+
334
+
335
+
336
+ function dbem_get_locations($eventful = false) {
337
+ global $wpdb;
338
+ $locations_table = $wpdb->prefix.LOCATIONS_TBNAME;
339
+ $events_table = $wpdb->prefix.EVENTS_TBNAME;
340
+ if ($eventful == 'true') {
341
+ $sql = "SELECT * from $locations_table JOIN $events_table ON $locations_table.location_id = $events_table.location_id";
342
+ } else {
343
+ $sql = "SELECT location_id, location_address, location_name, location_town,location_latitude, location_longitude
344
+ FROM $locations_table ORDER BY location_name";
345
+ }
346
+
347
+ $locations = $wpdb->get_results($sql, ARRAY_A);
348
+ return $locations;
349
+
350
+ }
351
+
352
+ function dbem_get_location($location_id) {
353
+ global $wpdb;
354
+ $locations_table = $wpdb->prefix.LOCATIONS_TBNAME;
355
+ $sql = "SELECT * FROM $locations_table WHERE location_id ='$location_id'";
356
+ $location = $wpdb->get_row($sql, ARRAY_A);
357
+ $location['location_image_url'] = dbem_image_url_for_location_id($location['location_id']);
358
+ return $location;
359
+
360
+ }
361
+
362
+ function dbem_image_url_for_location_id($location_id) {
363
+ $file_name= ABSPATH.IMAGE_UPLOAD_DIR."/location-".$location_id;
364
+ $mime_types = array('gif','jpg','png');
365
+ foreach($mime_types as $type) {
366
+ $file_path = "$file_name.$type";
367
+ if (file_exists($file_path)) {
368
+ $result = get_bloginfo('url')."/".IMAGE_UPLOAD_DIR."/location-$location_id.$type";
369
+ return $result;
370
+ }
371
+ }
372
+ return '';
373
+ }
374
+
375
+ function dbem_get_identical_location($location) {
376
+ global $wpdb;
377
+
378
+ $locations_table = $wpdb->prefix.LOCATIONS_TBNAME;
379
+ //$sql = "SELECT * FROM $locations_table WHERE location_name ='".$location['location_name']."' AND location_address ='".$location['location_address']."' AND location_town ='".$location['location_town']."';";
380
+ $prepared_sql=$wpdb->prepare("SELECT * FROM $locations_table WHERE location_name = %s AND location_address = %s AND location_town = %s", $location['location_name'], $location['location_address'], $location['location_town'] );
381
+ //$wpdb->show_errors(true);
382
+ $cached_location = $wpdb->get_row($prepared_sql, ARRAY_A);
383
+ return $cached_location;
384
+
385
+ }
386
+
387
+ function dbem_validate_location($location) {
388
+ global $location_required_fields;
389
+ $troubles = "";
390
+ foreach ($location_required_fields as $field => $description) {
391
+ if ($location[$field] == "" ) {
392
+ $troubles .= "<li>".$description.__(" is missing!", "dbem")."</li>";
393
+ }
394
+ }
395
+ if ($_FILES['location_image']['size'] > 0 ) {
396
+ if (is_uploaded_file($_FILES['location_image']['tmp_name'])) {
397
+ $mime_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
398
+ $maximum_size = get_option('dbem_image_max_size');
399
+ if ($_FILES['location_image']['size'] > $maximum_size)
400
+ $troubles = "<li>".__('The image file is too big! Maximum size:', 'dbem')." $maximum_size</li>";
401
+ list($width, $height, $type, $attr) = getimagesize($_FILES['location_image']['tmp_name']);
402
+ $maximum_width = get_option('dbem_image_max_width');
403
+ $maximum_height = get_option('dbem_image_max_height');
404
+ if (($width > $maximum_width) || ($height > $maximum_height))
405
+ $troubles .= "<li>". __('The image is too big! Maximum size allowed:')." $maximum_width x $maximum_height</li>";
406
+ if (($type!=1) && ($type!=2) && ($type!=3))
407
+ $troubles .= "<li>".__('The image is in a wrong format!')."</li>";
408
+ }
409
+ }
410
+
411
+ if ($troubles == "")
412
+ return "OK";
413
+ else {
414
+ $message = __('Ach, some problems here:', 'dbem')."<ul>\n$troubles</ul>";
415
+ return $message;
416
+ }
417
+ }
418
+
419
+ function dbem_update_location($location) {
420
+ global $wpdb;
421
+ $locations_table = $wpdb->prefix.LOCATIONS_TBNAME;
422
+ $sql="UPDATE ".$locations_table.
423
+ " SET location_name='".$location['location_name']."', ".
424
+ "location_address='".$location['location_address']."',".
425
+ "location_town='".$location['location_town']."', ".
426
+ "location_latitude=".$location['location_latitude'].",".
427
+ "location_longitude=".$location['location_longitude'].",".
428
+ "location_description='".$location['location_description']."' ".
429
+ "WHERE location_id='".$location['location_id']."';";
430
+ $wpdb->query($sql);
431
+
432
+ }
433
+
434
+ function dbem_insert_location($location) {
435
+
436
+ global $wpdb;
437
+ $table_name = $wpdb->prefix.LOCATIONS_TBNAME;
438
+ // if GMap is off the hidden fields are empty, so I add a custom value to make the query work
439
+ if (empty($location['location_longitude']))
440
+ $location['location_longitude'] = 0;
441
+ if (empty($location['location_latitude']))
442
+ $location['location_latitude'] = 0;
443
+ $sql = "INSERT INTO ".$table_name." (location_name, location_address, location_town, location_latitude, location_longitude, location_description)
444
+ VALUES ('".$location['location_name']."','".$location['location_address']."','".$location['location_town']."',".$location['location_latitude'].",".$location['location_longitude'].",'".$location['location_description']."')";
445
+ $wpdb->query($sql);
446
+ $new_location = dbem_get_location(mysql_insert_id());
447
+
448
+ return $new_location;
449
+ }
450
+
451
+ function dbem_delete_location($location) {
452
+ global $wpdb;
453
+ $table_name = $wpdb->prefix.LOCATIONS_TBNAME;
454
+ $sql = "DELETE FROM $table_name WHERE location_id = '$location';";
455
+ $wpdb->query($sql);
456
+ dbem_delete_image_files_for_location_id($location);
457
+ }
458
+
459
+ function dbem_location_has_events($location_id) {
460
+ global $wpdb;
461
+ $events_table = $wpdb->prefix.EVENTS_TBNAME;
462
+ $sql = "SELECT event_id FROM $events_table WHERE location_id = $location_id";
463
+ $affected_events = $wpdb->get_results($sql);
464
+ return (count($affected_events) > 0);
465
+ }
466
+
467
+ function dbem_upload_location_picture($location) {
468
+ if(!file_exists("../".IMAGE_UPLOAD_DIR))
469
+ mkdir("../".IMAGE_UPLOAD_DIR, 0777);
470
+ dbem_delete_image_files_for_location_id($location['location_id']);
471
+ $mime_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
472
+ list($width, $height, $type, $attr) = getimagesize($_FILES['location_image']['tmp_name']);
473
+ $image_path = "../".IMAGE_UPLOAD_DIR."/location-".$location['location_id'].".".$mime_types[$type];
474
+ if (!move_uploaded_file($_FILES['location_image']['tmp_name'], $image_path))
475
+ $msg = "<p>".__('The image could not be loaded','dbem')."</p>";
476
+ }
477
+ function dbem_delete_image_files_for_location_id($location_id) {
478
+ $file_name= "../".IMAGE_UPLOAD_DIR."/location-".$location_id;
479
+ $mime_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
480
+ foreach($mime_types as $type) {
481
+ if (file_exists($file_name.".".$type))
482
+ unlink($file_name.".".$type);
483
+ }
484
+ }
485
+
486
+
487
+
488
+ function dbem_global_map($atts) {
489
+ if (get_option('dbem_gmap_is_active') == '1') {
490
+ extract(shortcode_atts(array(
491
+ 'eventful' => "false",
492
+ 'scope' => 'all',
493
+ 'width' => 450,
494
+ 'height' => 300
495
+ ), $atts));
496
+ $events_page = dbem_get_events_page(true, false);
497
+ $gmaps_key = get_option('dbem_gmap_key');
498
+ $result = "<h3>Mappa totale</h3>";
499
+ $result .= "<div id='dbem_global_map' style='width: {$width}px; height: {$height}px'>map</div>";
500
+ $result .= "<script type='text/javascript'>
501
+ <!--//
502
+ eventful = $eventful;
503
+ scope = '$scope';
504
+ events_page = '$events_page';
505
+ GMapsKey = '$gmaps_key';
506
+ location_infos = '$location_infos'
507
+ //-->
508
+ </script>";
509
+ $result .= "<script src='".get_bloginfo('url')."/wp-content/plugins/events-manager/dbem_global_map.js' type='text/javascript'></script>";
510
+ $result .= "<ol id='dbem_locations_list'></ol>";
511
+
512
+ } else {
513
+ $result = "";
514
+ }
515
+ return $result;
516
+ }
517
+ add_shortcode('locations_map', 'dbem_global_map');
518
+
519
+ function dbem_replace_locations_placeholders($format, $location, $target="html") {
520
+ $location_string = $format;
521
+ preg_match_all("/#@?_?[A-Za-z]+/", $format, $placeholders);
522
+ foreach($placeholders[0] as $result) {
523
+ // echo "RESULT: $result <br>";
524
+ // matches alla fields placeholder
525
+ if (preg_match('/#_MAP/', $result)) {
526
+ $map_div = dbem_single_location_map($location);
527
+ $location_string = str_replace($result, $map_div , $location_string );
528
+
529
+ }
530
+ if (preg_match('/#_PASTEVENTS/', $result)) {
531
+ $list = dbem_events_in_location_list($location, "past");
532
+ $location_string = str_replace($result, $list , $location_string );
533
+ }
534
+ if (preg_match('/#_NEXTEVENTS/', $result)) {
535
+ $list = dbem_events_in_location_list($location);
536
+ $location_string = str_replace($result, $list , $location_string );
537
+ }
538
+ if (preg_match('/#_ALLEVENTS/', $result)) {
539
+ $list = dbem_events_in_location_list($location, "all");
540
+ $location_string = str_replace($result, $list , $location_string );
541
+ }
542
+
543
+ if (preg_match('/#_(NAME|ADDRESS|TOWN|PROVINCE|DESCRIPTION)/', $result)) {
544
+ $field = "location_".ltrim(strtolower($result), "#_");
545
+ $field_value = $location[$field];
546
+
547
+ if ($field == "location_description") {
548
+ if ($target == "html")
549
+ $field_value = apply_filters('dbem_notes', $field_value);
550
+ else
551
+ if ($target == "map")
552
+ $field_value = apply_filters('dbem_notes_map', $field_value);
553
+ else
554
+ $field_value = apply_filters('dbem_notes_rss', $field_value);
555
+ } else {
556
+ if ($target == "html")
557
+ $field_value = apply_filters('dbem_general', $field_value);
558
+ else
559
+ $field_value = apply_filters('dbem_general_rss', $field_value);
560
+ }
561
+ $location_string = str_replace($result, $field_value , $location_string );
562
+ }
563
+
564
+ if (preg_match('/#_(IMAGE)/', $result)) {
565
+
566
+ if($location['location_image_url'] != '')
567
+ $location_image = "<img src='".$location['location_image_url']."' alt='".$location['location_name']."'/>";
568
+ else
569
+ $location_image = "";
570
+ $location_string = str_replace($result, $location_image , $location_string );
571
+ }
572
+ if (preg_match('/#_(LOCATIONPAGEURL)/', $result)) {
573
+ $events_page_link = dbem_get_events_page(true, false);
574
+ if (stristr($events_page_link, "?"))
575
+ $joiner = "&amp;";
576
+ else
577
+ $joiner = "?";
578
+ $venue_page_link = dbem_get_events_page(true, false).$joiner."location_id=".$location['location_id'];
579
+ $location_string = str_replace($result, $venue_page_link , $location_string );
580
+ }
581
+
582
+ }
583
+ return $location_string;
584
+
585
+ }
586
+ function dbem_single_location_map($location) {
587
+ $gmap_is_active = get_option('dbem_gmap_is_active');
588
+ $map_text = dbem_replace_locations_placeholders(get_option('dbem_location_baloon_format'), $location);
589
+ if ($gmap_is_active) {
590
+ $gmaps_key = get_option('dbem_gmap_key');
591
+ $map_div = "<div id='dbem-location-map' style=' background: green; width: 400px; height: 300px'></div>" ;
592
+ $map_div .= "<script type='text/javascript'>
593
+ <!--//
594
+ latitude = parseFloat('".$location['location_latitude']."');
595
+ longitude = parseFloat('".$location['location_longitude']."');
596
+ GMapsKey = '$gmaps_key';
597
+ map_text = '$map_text';
598
+ //-->
599
+ </script>";
600
+ $map_div .= "<script src='".get_bloginfo('url')."/wp-content/plugins/events-manager/dbem_single_location_map.js' type='text/javascript'></script>";
601
+ } else {
602
+ $map_div = "";
603
+ }
604
+ return $map_div;
605
+ }
606
+
607
+ function dbem_events_in_location_list($location, $scope = "") {
608
+ $events = dbem_get_events("",$scope,"","",$location['location_id']);
609
+ $list = "";
610
+ if (count($events) > 0) {
611
+ foreach($events as $event)
612
+ $list .= dbem_replace_placeholders(get_option('dbem_location_event_list_item_format'), $event);
613
+ } else {
614
+ $list = get_option('dbem_location_no_events_message');
615
+ }
616
+ return $list;
617
+ }
618
+
619
+ add_action ('admin_head', 'dbem_locations_autocomplete');
620
+
621
+ function dbem_locations_autocomplete() {
622
+ if ((isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit_event') || (isset($_GET['page']) && $_GET['page'] == 'new_event')) {
623
+ ?>
624
+ <link rel="stylesheet" href="../wp-content/plugins/events-manager/js/jquery-autocomplete/jquery.autocomplete.css" type="text/css"/>
625
+
626
+
627
+ <script src="../wp-content/plugins/events-manager/js/jquery-autocomplete/lib/jquery.bgiframe.min.js" type="text/javascript"></script>
628
+ <script src="../wp-content/plugins/events-manager/js/jquery-autocomplete/lib/jquery.ajaxQueue.js" type="text/javascript"></script>
629
+
630
+ <script src="../wp-content/plugins/events-manager/js/jquery-autocomplete/jquery.autocomplete.min.js" type="text/javascript"></script>
631
+
632
+ <script type="text/javascript">
633
+ //<![CDATA[
634
+ $j=jQuery.noConflict();
635
+
636
+
637
+ $j(document).ready(function() {
638
+ var gmap_enabled = <?php echo get_option('dbem_gmap_is_active'); ?>;
639
+
640
+ $j("input#location-name").autocomplete("../wp-content/plugins/events-manager/locations-search.php", {
641
+ width: 260,
642
+ selectFirst: false,
643
+ formatItem: function(row) {
644
+ item = eval("(" + row + ")");
645
+ return item.name+'<br/><small>'+item.address+' - '+item.town+ '</small>';
646
+ },
647
+ formatResult: function(row) {
648
+ item = eval("(" + row + ")");
649
+ return item.name;
650
+ }
651
+
652
+ });
653
+ $j('input#location-name').result(function(event,data,formatted) {
654
+ item = eval("(" + data + ")");
655
+ $j('input#location-address').val(item.address);
656
+ $j('input#location-town').val(item.town);
657
+ if(gmap_enabled) {
658
+ eventLocation = $j("input#location-name").val();
659
+ eventTown = $j("input#location-town").val();
660
+ eventAddress = $j("input#location-address").val();
661
+
662
+ loadMap(eventLocation, eventTown, eventAddress)
663
+ }
664
+ });
665
+
666
+ });
667
+ //]]>
668
+
669
+ </script>
670
+
671
+ <?php
672
+
673
+ }
674
+ }
675
+
676
+
677
+ function dbem_cache_location($event){
678
+ $related_location = dbem_get_location_by_name($event['location_name']);
679
+ if (!$related_location) {
680
+ dbem_insert_location_from_event($event);
681
+ return;
682
+ }
683
+ if ($related_location->location_address != $event['location_address'] || $related_location->location_town != $event['location_town'] ) {
684
+ dbem_insert_location_from_event($event);
685
+ }
686
+
687
+ }
688
+
689
+ function dbem_get_location_by_name($name) {
690
+ global $wpdb;
691
+ $sql = "SELECT location_id,
692
+ location_name,
693
+ location_address,
694
+ location_town
695
+ FROM ".$wpdb->prefix.LOCATIONS_TBNAME.
696
+ " WHERE location_name = '$name'";
697
+ $event = $wpdb->get_row($sql);
698
+
699
+ return $event;
700
+ }
701
+
702
+ function dbem_insert_location_from_event($event) {
703
+ global $wpdb;
704
+ $table_name = $wpdb->prefix.LOCATIONS_TBNAME;
705
+ $wpdb->query("INSERT INTO ".$table_name." (location_name, location_address, location_town)
706
+ VALUES ('".$event['location_name']."', '".$event['location_address']."','".$event['location_town']."')");
707
+
708
+ }
dbem_people.php ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function dbem_people_page() {
3
+ // Managing AJAX booking removal
4
+ if(isset($_GET['action']) && $_GET['action'] == 'remove_booking') {
5
+ if(isset($_POST['booking_id']))
6
+ dbem_delete_booking($_POST['booking_id']);
7
+
8
+ }
9
+ ?>
10
+
11
+ <div class='wrap'>
12
+ <div id="icon-users" class="icon32"><br/></div>
13
+ <h2>People</h2>
14
+
15
+ <?php dbem_people_table(); ?>
16
+ </div>
17
+
18
+ <?php
19
+ }
20
+
21
+
22
+
23
+ add_action('init','dbem_ajax_actions');
24
+ function dbem_ajax_actions() {
25
+ if(isset($_GET['dbem_ajax_action']) && $_GET['dbem_ajax_action'] == 'booking_data') {
26
+ if(isset($_GET['id']))
27
+ echo "[ {bookedSeats:".dbem_get_booked_seats($_GET['id']).", availableSeats:".dbem_get_available_seats($_GET['id'])."}]";
28
+ die();
29
+ }
30
+ if(isset($_GET['action']) && $_GET['action'] == 'printable'){
31
+ if(isset($_GET['event_id']))
32
+ dbem_printable_booking_report($_GET['event_id']);
33
+ }
34
+
35
+ if(isset($_GET['query']) && $_GET['query'] == 'GlobalMapData') {
36
+ dbem_global_map_json($_GET['eventful']);
37
+ die();
38
+ }
39
+
40
+
41
+ }
42
+
43
+ function dbem_global_map_json($eventful = false) {
44
+
45
+ $json = '{"locations":[';
46
+ $locations = dbem_get_locations($eventful);
47
+ $json_locations = array();
48
+ foreach($locations as $location) {
49
+
50
+ $json_location = array();
51
+ foreach($location as $key => $value) {
52
+ $json_location[] = '"'.$key.'":"'.$value.'"';
53
+
54
+ }
55
+ $json_location[] = '"location_baloon":"'.dbem_replace_locations_placeholders(get_option('dbem_location_baloon_format'), $location).'"';
56
+ $json_locations[] = "{".implode(",",$json_location)."}";
57
+ }
58
+ $json .= implode(",", $json_locations);
59
+ $json .= "]}" ;
60
+ echo $json;
61
+ }
62
+
63
+
64
+
65
+
66
+ function dbem_printable_booking_report($event_id) {
67
+ $event = dbem_get_event($event_id);
68
+ $bookings = dbem_get_bookings_for($event_id);
69
+ $available_seats = dbem_get_available_seats($event_id);
70
+ $booked_seats = dbem_get_booked_seats($event_id);
71
+ $stylesheet = get_bloginfo('url')."/wp-content/plugins/events-manager/events_manager.css";
72
+ ?>
73
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
74
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
75
+ <html>
76
+ <head>
77
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
78
+ <title>Bookings for <?php echo $event['event_name'];?></title>
79
+ <link rel="stylesheet" href="<?php echo $stylesheet; ?>" type="text/css" media="screen" />
80
+
81
+ </head>
82
+ <body id="printable">
83
+ <div id="container">
84
+ <h1>Bookings for <?php echo $event['event_name'];?></h1>
85
+ <p><?php echo dbem_replace_placeholders("#d #M #Y", $event)?></p>
86
+ <p><?php echo dbem_replace_placeholders("#_LOCATION, #_ADDRESS, #_TOWN", $event)?></p>
87
+ <h2><?php _e('Bookings data', 'dbem');?></h2>
88
+ <table id="bookings-table">
89
+ <tr>
90
+ <th scope='col'><?php _e('Name', 'dbem')?></th>
91
+ <th scope='col'><?php _e('E-mail', 'dbem')?></th>
92
+ <th scope='col'><?php _e('Phone number', 'dbem')?></th>
93
+ <th scope='col'><?php _e('Seats', 'dbem')?></th>
94
+ <?php
95
+ foreach($bookings as $booking) { ?>
96
+ <tr>
97
+
98
+ <td><?php echo $booking['person_name']?></td>
99
+ <td><?php echo $booking['person_email']?></td>
100
+ <td><?php echo $booking['person_phone']?></td>
101
+ <td class='seats-number'><?php echo $booking['booking_seats']?></td>
102
+ </tr>
103
+ <?php } ?>
104
+ <tr id='booked-seats'>
105
+ <td colspan='2'>&nbsp;</td>
106
+ <td class='total-label'><?php _e('Booked', 'dbem')?>:</td>
107
+ <td class='seats-number'><?php echo $booked_seats; ?></td>
108
+ </tr>
109
+ <tr id='available-seats'>
110
+ <td colspan='2'>&nbsp;</td>
111
+ <td class='total-label'><?php _e('Available', 'dbem')?>:</td>
112
+ <td class='seats-number'><?php echo $available_seats; ?></td>
113
+ </tr>
114
+ </table>
115
+ </div>
116
+ </body>
117
+ </html>
118
+ <?php
119
+ die();
120
+
121
+ }
122
+
123
+ function dbem_people_table() {
124
+ $people = dbem_get_people();
125
+ if (count($people) < 1 ) {
126
+ _e("No people have responded to your events yet!", 'dbem');
127
+ } else {
128
+ $table = "<p>".__('This table collects the data about the people who responded to your events', 'dbem')."</p>";
129
+ $table .=" <table id='dbem-people-table' class='widefat post fixed'>\n
130
+ <thead>
131
+ <tr>
132
+ <th class='manage-column column-cb check-column' scope='col'>&nbsp;</th>\n
133
+ <th class='manage-column ' scope='col'>Name</th>\n
134
+ <th scope='col'>E-mail</th>\n
135
+ <th scope='col'>Phone number</th>\n
136
+ </tr>\n
137
+ </thead>\n
138
+ <tfoot>
139
+ <tr>
140
+ <th class='manage-column column-cb check-column' scope='col'>&nbsp;</th>\n
141
+ <th class='manage-column ' scope='col'>Name</th>\n
142
+ <th scope='col'>E-mail</th>\n
143
+ <th scope='col'>Phone number</th>\n
144
+ </tr>\n
145
+ </tfoot>\n
146
+ " ;
147
+ foreach ($people as $person) {
148
+ $table .= "<tr> <td>&nbsp;</td>
149
+ <td>".$person['person_name']."</td>
150
+ <td>".$person['person_email']."</td>
151
+ <td>".$person['person_phone']."</td></tr>";
152
+ }
153
+
154
+ $table .= "</table>";
155
+ echo $table;
156
+ }
157
+ }
158
+
159
+ function dbem_get_person_by_name_and_email($name, $email) {
160
+ global $wpdb;
161
+ $people_table = $wpdb->prefix.PEOPLE_TBNAME;
162
+ $sql = "SELECT person_id, person_name, person_email, person_phone FROM $people_table WHERE person_name = '$name' AND person_email = '$email' ;" ;
163
+ $result = $wpdb->get_row($sql, ARRAY_A);
164
+ return $result;
165
+ }
166
+
167
+ function dbem_get_person($person_id) {
168
+ global $wpdb;
169
+ $people_table = $wpdb->prefix.PEOPLE_TBNAME;
170
+ $sql = "SELECT person_id, person_name, person_email, person_phone FROM $people_table WHERE person_id = '$person_id';" ;
171
+ $result = $wpdb->get_row($sql, ARRAY_A);
172
+ return $result;
173
+ }
174
+
175
+ function dbem_get_people() {
176
+ global $wpdb;
177
+ $people_table = $wpdb->prefix.PEOPLE_TBNAME;
178
+ $sql = "SELECT * FROM $people_table";
179
+ $result = $wpdb->get_results($sql, ARRAY_A);
180
+ return $result;
181
+ }
182
+
183
+ function dbem_add_person($name, $email, $phone = "") {
184
+ global $wpdb;
185
+ $people_table = $wpdb->prefix.PEOPLE_TBNAME;
186
+ $sql = "INSERT INTO $people_table (person_name, person_email, person_phone) VALUES ('$name', '$email', '$phone');";
187
+ $wpdb->query($sql);
188
+ $new_person = dbem_get_person_by_name_and_email($name, $email);
189
+ return ($new_person);
190
+ }
191
+ add_action('edit_user_profile', 'dbem_phone_field') ;
192
+ function dbem_phone_field() {
193
+ ?>
194
+ <h3><?php _e('Phone number', 'dbem')?></h3>
195
+ <table class='form-table'>
196
+ <tr>
197
+ <th><?php _e('Phone number','dbem');?></th>
198
+ <td><input id="dbem_phone" class="regular-text" type="text" value="" name="dbem_phone"/> <br/>
199
+ <?php _e('The phone number used by Events Manager when the user is indicated as the contact person for an event.','dbem');?></td>
200
+ </tr>
201
+ </table>
202
+ <?php
203
+ }
204
+
205
+ add_action('profile_update','dbem_update_phone');
206
+ function dbem_update_phone($user_ID) {
207
+ if(isset($_POST['dbem_phone']) && $_POST['dbem_phone'] != '') {
208
+ update_usermeta($user_ID,'dbem_phone', $_POST['dbem_phone']);
209
+ }
210
+
211
+ }
212
+ function dbem_get_indexed_users() {
213
+ global $wpdb;
214
+ $sql = "SELECT display_name, ID FROM $wpdb->users";
215
+ $users = $wpdb->get_results($sql, ARRAY_A);
216
+ $indexed_users = array();
217
+ foreach($users as $user)
218
+ $indexed_users[$user['ID']] = $user['display_name'];
219
+ return $indexed_users;
220
+ }
221
+ ?>
dbem_rsvp.php ADDED
@@ -0,0 +1,379 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $form_add_message = "";
3
+ $form_delete_message = "";
4
+ function dbem_add_booking_form() {
5
+ global $form_add_message;
6
+ //$message = dbem_catch_rsvp();
7
+
8
+ $destination = "?".$_SERVER['QUERY_STRING']."#dbem-rsvp-form";
9
+ $module = "<h3>RSVP module</h3><br/>";
10
+ if(!empty($form_add_message))
11
+ $module .= "<div class='dbem-rsvp-message'>$form_add_message</div>";
12
+ $booked_places_options = array();
13
+ for ( $i = 1; $i <= 10; $i++)
14
+ array_push($booked_places_options, "<option value='$i'>$i</option>");
15
+
16
+ $module .= "<form id='dbem-rsvp-form' name='booking-form' method='post' action='$destination'>
17
+ <table class='dbem-rsvp-form'>
18
+ <tr><th scope='row'>Name:</th><td><input type='text' name='bookerName' value=''/></td></tr>
19
+ <tr><th scope='row'>E-mail:</th><td><input type='text' name='bookerEmail' value=''/></td></tr>
20
+ <tr><th scope='row'>Phone number:</th><td><input type='text' name='bookerPhone' value=''/></td></tr>
21
+ <tr><th scope='row'>How many seats?</th><td><select name='bookedSeats' >";
22
+ foreach($booked_places_options as $option) {
23
+ $module .= $option."\n";
24
+ }
25
+ $module .= "</select></td></tr>
26
+ </table>
27
+ <input type='submit' value='Send your booking'/>
28
+ <input type='hidden' name='eventAction' value='add_booking'/>
29
+ </form>";
30
+ // $module .= "dati inviati: ";
31
+ // $module .= $_POST['bookerName'];
32
+ //print_r($_SERVER);
33
+
34
+ //$module .= dbem_delete_booking_form();
35
+
36
+ return $module;
37
+
38
+ }
39
+
40
+ function dbem_delete_booking_form() {
41
+ global $form_delete_message;
42
+
43
+ $destination = "?".$_SERVER['QUERY_STRING'];
44
+ $module = "<h3>Delete module</h3><br/>";
45
+
46
+ if(!empty($form_delete_message))
47
+ $module .= "<div class='dbem-rsvp-message'>$form_delete_message</div>";
48
+
49
+
50
+ $module .= "<form name='booking-delete-form' method='post' action='$destination'>
51
+ <table class='dbem-rsvp-form'>
52
+ <tr><th scope='row'>Name:</th><td><input type='text' name='bookerName' value=''/></td></tr>
53
+ <tr><th scope='row'>E-mail:</th><td><input type='text' name='bookerEmail' value=''/></td></tr>
54
+ <input type='hidden' name='eventAction' value='delete_booking'/>
55
+ </table>
56
+ <input type='submit' value='Delete your booking'/>
57
+ </form>";
58
+ // $module .= "dati inviati: ";
59
+ // $module .= $_POST['bookerName'];
60
+
61
+
62
+
63
+ return $module;
64
+
65
+ }
66
+
67
+
68
+ function dbem_catch_rsvp() {
69
+ global $form_add_message;
70
+ global $form_delete_message;
71
+ if (isset($_POST['eventAction']) && $_POST['eventAction'] == 'add_booking') {
72
+ $result = dbem_book_seats();
73
+ $form_add_message = $result;
74
+
75
+
76
+ }
77
+
78
+ if (isset($_POST['eventAction']) && $_POST['eventAction'] == 'delete_booking') {
79
+
80
+ $bookerName = $_POST['bookerName'];
81
+ $bookerEmail = $_POST['bookerEmail'];
82
+ $booker = dbem_get_person_by_name_and_email($bookerName, $bookerEmail);
83
+ if ($booker) {
84
+ $booker_id = $booker['person_id'];
85
+ $booking = dbem_get_booking_by_person_id($booker_id);
86
+ $result = dbem_delete_booking($booking['booking_id']);
87
+ } else {
88
+ $result = __('There are no bookings associated to this name and e-mail', 'dbem');
89
+ }
90
+ $form_delete_message = $result;
91
+ }
92
+
93
+ return $result;
94
+
95
+ }
96
+ add_action('init','dbem_catch_rsvp');
97
+
98
+
99
+
100
+ function dbem_book_seats() {
101
+ $bookerName = $_POST['bookerName'];
102
+ $bookerEmail = $_POST['bookerEmail'];
103
+ $bookerPhone = $_POST['bookerPhone'];
104
+ $bookedSeats = $_POST['bookedSeats'];
105
+ $event_id = $_GET['event_id'];
106
+ $booker = dbem_get_person_by_name_and_email($bookerName, $bookerEmail);
107
+ if (!$booker) {
108
+ $booker = dbem_add_person($bookerName, $bookerEmail, $bookerPhone);
109
+ }
110
+ if (dbem_are_seats_available_for($event_id, $bookedSeats)) {
111
+ dbem_record_booking($event_id, $booker['person_id'], $bookedSeats);
112
+
113
+ $result = __('Your booking has been recorded','dbem');
114
+ $mailing_is_active = get_option('dbem_rsvp_mail_notify_is_active');
115
+ if($mailing_is_active) {
116
+ dbem_email_rsvp_booking();
117
+ }
118
+
119
+ } else {
120
+ $result = __('Sorry, there aren\'t so many seats available!', 'dbem');
121
+ }
122
+ return $result;
123
+ }
124
+
125
+
126
+
127
+ function dbem_get_booking_by_person_id($person_id) {
128
+ global $wpdb;
129
+ $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
130
+ $sql = "SELECT * FROM $bookings_table WHERE person_id = '$person_id';" ;
131
+ $result = $wpdb->get_row($sql, ARRAY_A);
132
+ return $result;
133
+ }
134
+
135
+ function dbem_record_booking($event_id, $person_id, $seats) {
136
+ global $wpdb;
137
+ $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
138
+ // checking whether the booker has already booked places
139
+ $sql = "SELECT * FROM $bookings_table WHERE event_id = '$event_id' and person_id = '$person_id'; ";
140
+ //echo $sql;
141
+ $previously_booked = $wpdb->get_row($sql);
142
+ if ($previously_booked) {
143
+
144
+ $total_booked_seats = $previously_booked->booking_seats + $seats;
145
+ $where = array();
146
+ $where['booking_id'] =$previously_booked->booking_id;
147
+ $fields['booking_seats'] = $total_booked_seats;
148
+ $wpdb->update($bookings_table, $fields, $where);
149
+
150
+ } else {
151
+ if(true) {
152
+ $sql = "INSERT INTO $bookings_table (event_id, person_id, booking_seats) VALUES ($event_id, $person_id, $seats)";
153
+ $wpdb->query($sql);
154
+ echo $sql;
155
+ }
156
+ }
157
+ }
158
+ function dbem_delete_booking($booking_id) {
159
+ global $wpdb;
160
+ $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
161
+ $sql = "DELETE FROM $bookings_table WHERE booking_id = $booking_id";
162
+ $wpdb->query($sql);
163
+ return __('Booking deleted', 'dbem');
164
+ }
165
+
166
+ function dbem_get_available_seats($event_id) {
167
+ global $wpdb;
168
+ $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
169
+ $sql = "SELECT SUM(booking_seats) AS booked_seats FROM $bookings_table WHERE event_id = $event_id";
170
+ $seats_row = $wpdb->get_row($sql, ARRAY_A);
171
+ $booked_seats = $seats_row['booked_seats'];
172
+ $event = dbem_get_event($event_id);
173
+ $available_seats = $event['event_seats'] - $booked_seats;
174
+ return ($available_seats);
175
+ }
176
+ function dbem_get_booked_seats($event_id) {
177
+ global $wpdb;
178
+ $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
179
+ $sql = "SELECT SUM(booking_seats) AS booked_seats FROM $bookings_table WHERE event_id = $event_id";
180
+ $seats_row = $wpdb->get_row($sql, ARRAY_A);
181
+ $booked_seats = $seats_row['booked_seats'];
182
+ return $booked_seats;
183
+ }
184
+ function dbem_are_seats_available_for($event_id, $seats) {
185
+ $event = dbem_get_event($event_id);
186
+ $available_seats = dbem_get_available_seats($event_id);
187
+ $remaning_seats = $available_seats - $seats;
188
+ return ($remaning_seats >= 0);
189
+ }
190
+
191
+ function dbem_bookings_table($event_id) {
192
+
193
+ $bookings = dbem_get_bookings_for($event_id);
194
+ $destination = get_bloginfo('url')."/wp-admin/edit.php";
195
+ $table = "<form id='bookings-filter' method='get' action='$destination'>
196
+ <input type='hidden' name='page' value='events-manager/events-manager.php'/>
197
+ <input type='hidden' name='action' value='edit_event'/>
198
+ <input type='hidden' name='event_id' value='$event_id'/>
199
+ <input type='hidden' name='secondaryAction' value='delete_bookings'/>
200
+ <div class='wrap'>
201
+ <h2>Bookings</h2>\n
202
+ <table id='dbem-bookings-table' class='widefat post fixed'>\n";
203
+ $table .="<thead>\n
204
+ <tr><th class='manage-column column-cb check-column' scope='col'>&nbsp;</th><th class='manage-column ' scope='col'>Booker</th><th scope='col'>E-mail</th><th scope='col'>Phone number</th><th scope='col'>Seats</th></tr>\n
205
+ </thead>\n" ;
206
+ foreach ($bookings as $booking) {
207
+ $table .= "<tr> <td><input type='checkbox' value='".$booking['booking_id']."' name='bookings[]'/></td>
208
+ <td>".$booking['person_name']."</td>
209
+ <td>".$booking['person_email']."</td>
210
+ <td>".$booking['person_phone']."</td>
211
+ <td>".$booking['booking_seats']."</td></tr>";
212
+ }
213
+ $available_seats = dbem_get_available_seats($event_id);
214
+ $booked_seats = dbem_get_booked_seats($event_id);
215
+ $table .= "<tfoot><tr><th scope='row' colspan='4'>Booked seats:</th><td class='booking-result' id='booked-seats'>$booked_seats</td></tr>
216
+ <tr><th scope='row' colspan='4'>Available seats:</th><td class='booking-result' id='available-seats'>$available_seats</td></tr></tfoot>
217
+ </table></div>
218
+ <div class='tablenav'>
219
+ <div class='alignleft actions'>
220
+ <input class=button-secondary action' type='submit' name='doaction2' value='Delete'/>
221
+ <br class='clear'/>
222
+ </div>
223
+ <br class='clear'/>
224
+ </div>
225
+
226
+ </form>";
227
+ echo $table;
228
+ }
229
+
230
+ function dbem_bookings_compact_table($event_id) {
231
+
232
+ $bookings = dbem_get_bookings_for($event_id);
233
+ $destination = get_bloginfo('url')."/wp-admin/edit.php";
234
+ $available_seats = dbem_get_available_seats($event_id);
235
+ $booked_seats = dbem_get_booked_seats($event_id);
236
+ $printable_address = get_bloginfo('url')."/wp-admin/admin.php?page=people&action=printable&event_id=$event_id";
237
+ if (count($bookings)>0) {
238
+ $table =
239
+ "<div class='wrap'>
240
+ <h4>$booked_seats ".__('responses so far').":</h4>\n
241
+
242
+ <table id='dbem-bookings-table-$event_id' class='widefat post fixed'>\n
243
+ <thead>\n
244
+ <tr>
245
+ <th class='manage-column column-cb check-column' scope='col'>&nbsp;</th>\n
246
+ <th class='manage-column ' scope='col'>".__('Responder', 'dbem')."</th>\n
247
+ <th scope='col'>".__('Spaces', 'dbem')."</th>\n
248
+ </tr>\n
249
+ </thead>\n
250
+ <tfoot>
251
+ <tr>
252
+ <th scope='row' colspan='2'>".__('Booked spaces','dbem').":</th><td class='booking-result' id='booked-seats'>$booked_seats</td></tr>
253
+ <tr><th scope='row' colspan='2'>".__('Available spaces','dbem').":</th><td class='booking-result' id='available-seats'>$available_seats</td>
254
+ </tr>
255
+ </tfoot>
256
+ <tbody>" ;
257
+ foreach ($bookings as $booking) {
258
+ $table .=
259
+ "<tr id='booking-".$booking['booking_id']."'>
260
+ <td><a id='booking-check-".$booking['booking_id']."' class='bookingdelbutton'>X</a></td>
261
+ <td><a title='".$booking['person_email']." - ".$booking['person_phone']."'>".$booking['person_name']."</a></td>
262
+ <td>".$booking['booking_seats']."</td>
263
+ </tr>";
264
+ }
265
+
266
+ $table .= "</tbody>\n
267
+
268
+ </table>
269
+ </div>
270
+
271
+ <br class='clear'/>
272
+ <div id='major-publishing-actions'>
273
+ <div id='publishing-action'>
274
+ <a id='printable' target='' href='$printable_address'>".__('Printable view','dbem')."</a>
275
+ <br class='clear'/>
276
+
277
+
278
+ </div>
279
+ <br class='clear'/>
280
+ </div> ";
281
+ } else {
282
+ $table .= "<p><em>".__('No responses yet!')."</em></p>";
283
+ }
284
+
285
+ echo $table;
286
+ }
287
+
288
+ function dbem_get_bookings_for($event_id) {
289
+ global $wpdb;
290
+ $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
291
+ $sql = "SELECT * FROM $bookings_table WHERE event_id = $event_id";
292
+ $bookings = $wpdb->get_results($sql, ARRAY_A);
293
+ $booking_data = array();
294
+ if ($bookings) {
295
+ foreach ($bookings as $booking) {
296
+ $booking;
297
+ $person = dbem_get_person($booking['person_id']);
298
+ $booking['person_name'] = $person['person_name'];
299
+ $booking['person_email'] = $person['person_email'];
300
+ $booking['person_phone'] = $person['person_phone'];
301
+ array_push($booking_data, $booking);
302
+ }
303
+ return $booking_data;
304
+ } else {
305
+ return null;
306
+ }
307
+ }
308
+
309
+ function dbem_intercept_bookings_delete() {
310
+ //dbem_email_rsvp_booking();
311
+ $bookings = $_GET['bookings'];
312
+
313
+ if ($bookings) {
314
+ foreach($bookings as $booking_id) {
315
+ dbem_delete_booking($booking_id);
316
+ }
317
+ }
318
+ }
319
+ add_action('init', 'dbem_intercept_bookings_delete');
320
+
321
+ function dbem_email_rsvp_booking(){
322
+ $booker = array();
323
+ $bookerName = $_POST['bookerName'];
324
+ $bookerEmail = $_POST['bookerEmail'];
325
+ $bookerPhone = $_POST['bookerPhone'];
326
+ $bookedSeats = $_POST['bookedSeats'];
327
+ $event_id = $_GET['event_id'];
328
+
329
+
330
+ $event = dbem_get_event($event_id);
331
+ $available_seats = dbem_get_available_seats($event_id);
332
+ $reserved_seats = dbem_get_booked_seats($event_id);
333
+
334
+ if($event['event_contactperson_id'] != "")
335
+ $contact_id = $event['event_contactperson_id'];
336
+ else
337
+ $contact_id = get_option('dbem_default_contact_person');
338
+
339
+ $contact_name = dbem_get_user_name($contact_id);
340
+
341
+ $contact_body = dbem_replace_placeholders(get_option('dbem_contactperson_email_body'), $event);
342
+ $booker_body = dbem_replace_placeholders(get_option('dbem_respondent_email_body'), $event);
343
+
344
+ // email specific placeholders
345
+ $placeholders = array('#_CONTACTPERSON'=> $contact_name, '#_RESPNAME' => $bookerName, '#_RESPEMAIL' => $bookerEmail, '#_SPACES' => $bookedSeats, '#_RESERVEDSPACES' => $reserved_seats, '#_AVAILABLESPACES' => $available_seats);
346
+
347
+ foreach($placeholders as $key => $value) {
348
+ $contact_body= str_replace($key, $value, $contact_body);
349
+ $booker_body= str_replace($key, $value, $booker_body);
350
+ }
351
+
352
+ $contact_email = dbem_get_user_email($contact_id);
353
+ dbem_send_mail(__("New booking",'dbem'), $contact_body, $contact_email);
354
+ dbem_send_mail(__('Reservation confirmed','dbem'),$booker_body, $bookerEmail);
355
+
356
+ }
357
+
358
+ function dbem_get_user_email($user_id) {
359
+ global $wpdb;
360
+ $sql = "SELECT user_email FROM $wpdb->users WHERE ID = $user_id";
361
+ return $wpdb->get_var( $wpdb->prepare($sql) );
362
+ }
363
+ function dbem_get_user_name($user_id) {
364
+ global $wpdb;
365
+ $sql = "SELECT display_name FROM $wpdb->users WHERE ID = $user_id";
366
+ return $wpdb->get_var( $wpdb->prepare($sql) );
367
+ }
368
+ function dbem_get_user_phone($user_id) {
369
+ return get_usermeta($user_id, 'dbem_phone');
370
+ }
371
+
372
+ // got from http://davidwalsh.name/php-email-encode-prevent-spam
373
+ function dbem_ascii_encode($e)
374
+ {
375
+ for ($i = 0; $i < strlen($e); $i++) { $output .= '&#'.ord($e[$i]).';'; }
376
+ return $output;
377
+ }
378
+
379
+ ?>
dbem_single_location_map.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $j=jQuery.noConflict();
2
+ //console.log("single location map");
3
+
4
+ $j(document.body).unload(function() {
5
+ if (GBrowserIsCompatible()) {
6
+ GUnload();
7
+ }
8
+ });
9
+
10
+
11
+ $j(document).ready(function() {
12
+ loadMapScript(GMapsKey);
13
+ });
14
+
15
+ function loadMapScript(key) {
16
+ var script = document.createElement("script");
17
+ script.setAttribute("src", "http://maps.google.com/maps?file=api&v=2.x&key=" + key + "&c&async=2&callback=loadGMap");
18
+ script.setAttribute("type", "text/javascript");
19
+ document.documentElement.firstChild.appendChild(script);
20
+ }
21
+
22
+ function loadGMap() {
23
+ if (GBrowserIsCompatible()) {
24
+ map = new GMap2(document.getElementById("dbem-location-map"));
25
+ point = new GLatLng(latitude, longitude);
26
+ mapCenter= new GLatLng(point.lat()+0.005, point.lng()-0.003);
27
+ map.setCenter(mapCenter, 14);
28
+ var marker = new GMarker(point);
29
+ map.addOverlay(marker);
30
+ marker.openInfoWindowHtml(map_text);
31
+ }
32
+ }
events-manager.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
  /*
3
  Plugin Name: Events Manager
4
- Version: 1.0.1
5
  Plugin URI: http://davidebenini.it/wordpress-plugins/events-manager/
6
- Description: Manage events specifying precise spatial data (Venue, Town, Province, etc).
7
  Author: Davide Benini
8
  Author URI: http://www.davidebenini.it/blog
9
  */
@@ -27,10 +27,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27
  */
28
 
29
  /*************************************************/
30
- include("dbem_calendar.php");
31
- include("dbem_widgets.php");
32
  // Setting constants
33
- define('TBNAME','events'); //TABLE NAME
 
 
 
 
 
34
  define('DEFAULT_EVENT_PAGE_NAME', 'Events');
35
  define('DBEM_PAGE','<!--DBEM_EVENTS_PAGE-->'); //EVENTS PAGE
36
  define('MIN_CAPABILITY', 'edit_posts'); // Minimum user level to access calendars
@@ -39,16 +43,55 @@ define('DEFAULT_EVENT_LIST_ITEM_FORMAT', '<li>#j #M #Y - #H:#i<br/> #_LINKEDNAME
39
  define('DEFAULT_SINGLE_EVENT_FORMAT', '<p>#j #M #Y - #H:#i</p><p>#_TOWN</p>');
40
  define('DEFAULT_EVENTS_PAGE_TITLE',__('Events','dbem') ) ;
41
  define('DEFAULT_EVENT_PAGE_TITLE_FORMAT', ' #_NAME');
42
- define('DEFAULT_RSS_DESCRIPTION_FORMAT',"#j #M #y - #H:#i <br/>#_VENUE <br/>#_ADDRESS <br/>#_TOWN");
43
  define('DEFAULT_RSS_TITLE_FORMAT',"#_NAME");
44
- define('DEFAULT_MAP_TEXT_FORMAT', '<strong>#_VENUE</strong><p>#_ADDRESS</p><p>#_TOWN</p>');
45
  define('DEFAULT_WIDGET_EVENT_LIST_ITEM_FORMAT','<li>#_LINKEDNAME<ul><li>#j #M #y</li><li>#_TOWN</li></ul></li>');
46
- define('DEFAULT_NO_EVENTS_MESSAGE', __('No events', 'dbem'));
 
 
 
 
 
 
 
 
 
47
  // DEBUG constant for developing
48
  // if you are hacking this plugin, set to TRUE, alog will show in admin pages
 
 
 
49
  define('DEBUG', false);
50
 
51
- load_plugin_textdomain('dbem', "/wp-content/plugins/events-manager/");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  // To enable activation through the activate function
53
  register_activation_hook(__FILE__,'events-manager');
54
 
@@ -75,11 +118,57 @@ add_filter('dbem_notes_rss', 'ent2ncr', 8);
75
 
76
  add_filter('dbem_notes_map', 'convert_chars', 8);
77
  add_filter('dbem_notes_map', 'js_escape');
 
 
78
 
79
  /* Creating the wp_events table to store event data*/
80
  function dbem_install() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  global $wpdb, $user_level;
82
- $table_name = $wpdb->prefix.TBNAME;
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
84
  // check the user is allowed to make changes
85
  // get_currentuserinfo();
@@ -90,17 +179,19 @@ function dbem_install() {
90
  event_id mediumint(9) NOT NULL AUTO_INCREMENT,
91
  event_author mediumint(9) NOT NULL,
92
  event_name tinytext NOT NULL,
93
- event_time datetime NOT NULL,
94
- event_venue tinytext NOT NULL,
95
- event_address tinytext NOT NULL,
96
- event_town tinytext NOT NULL,
97
- event_province tinytext,
98
  event_notes text NOT NULL,
99
- event_latitude float DEFAULT NULL,
100
- event_longitude float DEFAULT NULL,
 
 
 
101
  UNIQUE KEY (event_id)
102
  );";
103
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
104
  dbDelta($sql);
105
  //-------------- DEBUG CODE to insert a few events n the new table
106
  // get the current timestamp into an array
@@ -116,644 +207,284 @@ function dbem_install() {
116
 
117
  // use mktime to recreate the unix timestamp
118
  // adding 19 hours to $hours
119
- $in_one_week = strftime('%Y-%m-%d 21:30:00', mktime($hours,$minutes,$seconds,$month,$day+7,$year));
120
- $in_four_weeks = strftime('%Y-%m-%d 16:00:00',mktime($hours,$minutes,$seconds,$month,$day+28,$year));
121
- $in_one_year = strftime('%Y-%m-%d 22:00:00',mktime($hours,$minutes,$seconds,$month,$day,$year+1));
122
 
123
- $wpdb->query("INSERT INTO ".$wpdb->prefix."events (event_name, event_venue, event_address, event_time, event_town)
124
- VALUES ('Monster gig','Wembley stadium', 'Wembley', '$in_one_week','London')");
125
- $wpdb->query("INSERT INTO ".$wpdb->prefix."events (event_name, event_venue,event_address, event_time, event_town)
126
- VALUES ('Fiesta Mexicana','Hard Rock Cafe', '1501 Broadway', '$in_four_weeks','New York')");
127
- $wpdb->query("INSERT INTO ".$wpdb->prefix."events (event_name, event_venue,event_address, event_time, event_town)
128
- VALUES ('Gladiators fight','Arena', 'Piazza Bra', '$in_one_year','Verona')");
 
 
 
 
 
 
 
 
 
 
 
129
  }
 
130
 
131
-
132
-
133
- $events_page_id = get_option('dbem_events_page') ;
134
- if ($events_page_id != "" ) {
135
- query_posts("page_id=$events_page_id");
136
- $count = 0;
137
- while(have_posts()) { the_post();
138
- $count++;
139
- }
140
- if ($count == 0)
141
- dbem_create_events_page();
142
- } else {
143
- dbem_create_events_page();
144
- }
145
- //if (get_option('dbem_events_page'))
146
- //$event_page_id = get_option('dbem_events_page');
147
- //dbem_create_events_page();
148
- // Adding plugin options
149
- $event_list_item_format = get_option('dbem_event_list_item_format');
150
- if (empty($event_list_item_format))
151
- update_option('dbem_event_list_item_format', DEFAULT_EVENT_LIST_ITEM_FORMAT);
152
-
153
- $single_event_format = get_option('dbem_single_event_format');
154
- if (empty($single_event_format))
155
- update_option('dbem_single_event_format', DEFAULT_SINGLE_EVENT_FORMAT);
156
-
157
- $event_page_title_format = get_option('dbem_event_page_title_format');
158
- if (empty($event_page_title_format))
159
- update_option('dbem_event_page_title_format', DEFAULT_EVENT_PAGE_TITLE_FORMAT);
160
 
161
- $list_events_page = get_option('dbem_list_events_page');
162
- if (empty($list_events_page))
163
- update_option('dbem_list_events_page', 0);
164
-
165
- $events_page_title = get_option('dbem_events_page_title');
166
- if (empty($events_page_title))
167
- update_option('dbem_events_page_title', DEFAULT_EVENTS_PAGE_TITLE);
168
-
169
- $no_events_message = get_option('dbem_no_events_message');
170
- if (empty($no_events_message))
171
- update_option('dbem_no_events_message', __('No events','dbem'));
172
-
173
- $map_text_format = get_option('dbem_map_text_format');
174
- if (empty($map_text_format))
175
- update_option('dbem_map_text_format', DEFAULT_MAP_TEXT_FORMAT);
176
-
177
- $rss_main_title = get_option('dbem_rss_main_title');
178
- if (empty($rss_main_title)) {
179
- $default_rss_main_title = get_bloginfo('title')." - ".__('Events');
180
- update_option('dbem_rss_main_title', $default_rss_main_title);
181
- }
182
-
183
- $rss_main_description = get_option('dbem_rss_main_description');
184
- if (empty($rss_main_description)) {
185
- $default_rss_main_description = get_bloginfo('description')." - ".__('Events');
186
- update_option('dbem_rss_main_description', $default_rss_main_description);
187
- }
188
-
189
- $rss_description_format = get_option('dbem_rss_description_format');
190
- if (empty($rss_description_format))
191
- update_option('dbem_rss_description_format', DEFAULT_RSS_DESCRIPTION_FORMAT);
192
-
193
- $rss_title_format = get_option('dbem_rss_title_format');
194
- if (empty($rss_title_format))
195
- update_option('dbem_rss_title_format', DEFAULT_RSS_TITLE_FORMAT);
196
-
197
- $gmap_is_active = get_option('dbem_gmap_is_active');
198
- if(empty($gmap_is_active))
199
- update_option('dbem_gmap_is_active', 0);
200
-
201
- $gmap_key = get_option('dbem_gmap_key');
202
- if (empty($gmap_key))
203
- update_option('dbem_gmap_key', '');
204
-
205
- }
206
-
207
- function dbem_create_events_page(){
208
- echo "inserimento pagina";
209
- global $wpdb,$current_user;
210
- $page_name= DEFAULT_EVENT_PAGE_NAME;
211
- $sql= "INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_type, post_content, post_title, post_name, post_modified, post_modified_gmt, comment_count) VALUES ($current_user->ID, '$now', '$now_gmt', 'page','CONTENTS', '$page_name', '".$wpdb->escape(__('Events','dbem'))."', '$now', '$now_gmt', '0')";
212
- // echo($sql);
213
- $wpdb->query($sql);
214
-
215
- update_option('dbem_events_page', mysql_insert_id());
216
- }
217
 
218
- // Create the Manage Events and the Options submenus
219
- add_action('admin_menu','dbem_create_events_submenu');
220
- function dbem_create_events_submenu () {
221
- if(function_exists('add_submenu_page')) {
222
- add_submenu_page('edit.php',__('Events', 'dbem'),__('Events', 'dbem'),MIN_CAPABILITY,'eventmanager.php',dbem_events_subpanel);
223
- // add_options_page('Events Manager','Events Manager',MIN_LEVEL,'eventmanager.php',dbem_options_subpanel);
224
- add_options_page('Events manager', 'Events Manager', SETTING_CAPABILITY, __FILE__, dbem_options_subpanel);
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
- }
227
- }
228
-
229
- // Events manager page
230
- function dbem_events_subpanel() {
231
-
232
-
233
-
234
- global $wpdb;
235
- $action=$_GET['action'];
236
- $element=$_GET['event_id'];
237
- $scope=$_GET['scope'];
238
- $offset=$_GET['offset'];
239
- $order=$_GET['order'];
240
- if ($order == "")
241
- $order = "ASC";
242
- if ($offset=="")
243
- $offset = "0";
244
-
245
- // Debug code, to make sure I get the correct page
246
- //$event_page_id=get_option('dbem_event_page');
247
- if (DEBUG) {
248
- echo "<div class='debug'>\n
249
- \t<h3>Debug log</h3>\n";
250
- echo "<p>action = $action $element</p>\n";
251
-
252
- }
253
- // DELETE action
254
- if ($action == 'delete_event') {
255
- $sql="DELETE FROM ".$wpdb->prefix."events WHERE event_id='"."$element"."'";
256
- if (DEBUG)
257
- echo $sql;
258
- // TODO eventual error if ID in non-existant
259
- $wpdb->query($sql);
260
- if (DEBUG)
261
- echo "</div>"; // end of debug div
262
- $events = dbem_get_events("", "future");
263
- dbem_events_table($events, 10,"Future events");
264
- }
265
- // UPDATE or CREATE action
266
- if ($action == 'update_event') {
267
- // This script gets executed whenever has inserted a new event or updated an old one
268
- $event = array();
269
- $event['event_name']=$_POST[event_name];
270
- $event['event_day']=$_POST[event_day];
271
- $event['event_month']=$_POST[event_month];
272
- $event['event_year']=$_POST[event_year];
273
- $event['event_hh']=$_POST[event_hh];
274
- $event['event_mm']=$_POST[event_mm];
275
- $event['event_venue']=$_POST[event_venue];
276
- $event['event_address']=$_POST[event_address];
277
- $event['event_town']=$_POST[event_town];
278
- $event['event_province']=$_POST[event_province];
279
- $event['event_latitude']=$_POST[event_latitude];
280
- $event['event_longitude']=$_POST[event_longitude];
281
- $event['event_notes']=$_POST[event_notes];
282
- $datetime="'{$event['event_year']}-{$event['event_month']}-{$event['event_day']} {$event['event_hh']}:{$event['event_mm']}:00'";
283
- // $datetime="$event_day-$event_month-$event_year $event_hh:$event_mm:00";
284
- $validation_result = dbem_validate_event($event);
285
- if ( $validation_result == "OK") {
286
- // validation successful
287
- if(!$element) {
288
- // INSERT new event
289
- $sql="INSERT INTO ".$wpdb->prefix."events (event_name, event_venue, event_town, event_address, event_province, event_time, event_latitude, event_longitude, event_notes)
290
- VALUES ('".$event['event_name']."','".$event['event_venue']."','".$event['event_town']."','".$event['event_address']."','".$event['event_province']."',".$datetime.",'".$event['event_latitude']."','".$event['event_longitude']."','".$event['event_notes']."');";
291
- $feedback_message = __('New event successfully inserted!','dbem');
292
- } else {
293
- // UPDATE old event
294
- $sql="UPDATE ".$wpdb->prefix."events
295
- SET event_name='".$event['event_name']."', ".
296
- "event_venue='".$event['event_venue']."',".
297
- "event_town='".$event['event_town']."',".
298
- "event_address='".$event['event_address']."',".
299
- "event_province='".$event['event_province']."',".
300
- "event_latitude='".$event['event_latitude']."',".
301
- "event_longitude='".$event['event_longitude']."',".
302
- "event_notes='".$event['event_notes']."',".
303
- "event_time=$datetime ".
304
- "WHERE event_id="."$element";
305
- $feedback_message = __('Event','dbem')." $element ".__('updated','dbem')."!";
306
- }
307
- if (DEBUG)
308
- echo "SQL = $sql";
309
- if (DEBUG)
310
- echo "</div>"; // end of debug
311
-
312
- $wpdb->query($sql);
313
- echo "<div id='message' class='updated fade'>
314
- <p>$feedback_message</p>
315
- </div>";
316
- $events = dbem_get_events("", "future");
317
- dbem_events_table($events, 10, "Future events");
318
- } else {
319
- // validation unsuccessful
320
-
321
- echo $event['name'];
322
- if (DEBUG)
323
- echo "<p>NON VALIDO: $validation_result</p>";
324
- if (DEBUG)
325
- echo "</div>"; // end of debug
326
- echo "<div id='message' class='error '>
327
- <p>Ach, there's a problem here: $validation_result</p>
328
- </div>";
329
- dbem_event_form($event,"Edit event $element" ,$element);
330
-
331
- }
332
- }
333
- if ($action == 'edit_event') {
334
- if (!$element) {
335
- $title=__("Insert New Event", 'dbem');
336
- } else {
337
- $title=__("Edit Event", 'dbem')." $element";
338
- }
339
- // If a edit operation was requested queries the event table
340
- $sql='SELECT event_id,
341
- event_name,
342
- event_venue,
343
- event_address,
344
- event_town,
345
- event_province,
346
- DATE_FORMAT(event_time, "%e") AS "event_day",
347
- DATE_FORMAT(event_time, "%c") AS "event_month",
348
- DATE_FORMAT(event_time, "%Y") AS "event_year",
349
- DATE_FORMAT(event_time, "%k") AS "event_hh",
350
- DATE_FORMAT(event_time, "%i") AS "event_mm",
351
- event_latitude,
352
- event_longitude,
353
- event_notes
354
- FROM '.$wpdb->prefix.'events WHERE event_id="'.$element.'";';
355
- $event=$wpdb->get_row($sql, ARRAY_A);
356
- // Enter new events and updates old ones
357
- // DEBUG: echo"Nome: $event->event_name";
358
- if (DEBUG) {
359
- echo "</div>";
360
- }
361
-
362
- dbem_event_form($event, $title, $element);
363
-
364
- }
365
- if ($action == ""){
366
- // No action, only showing the events list
367
- if (DEBUG)
368
- echo "\t<p>No UPDATE, INSERT or DELETE action performed</p>\n
369
- </div>";
370
-
371
-
372
- switch ($scope) {
373
- case "past":
374
- $title = __('Past Events','dbem');
375
- break;
376
- case "all":
377
- $title = __('All Events','dbem');
378
- break;
379
- default:
380
- $title = __('Future Events','dbem');
381
- $scope = "future";
382
- }
383
- $limit = 10;
384
- $events = dbem_get_events($limit, $scope, $order,$offset);
385
-
386
- dbem_events_table($events, $limit, $title);
387
-
388
  }
389
-
390
-
391
- }
392
-
393
- // Function composing the options subpanel
394
- function dbem_options_subpanel() {
395
-
396
- ?>
397
- <div class="wrap">
398
- <h2><?php _e('Event Manager Options','dbem'); ?></h2>
399
- <form id="dbem_options_form" method="post" action="options.php">
400
- <?php wp_nonce_field('update-options'); ?>
401
- <table class="form-table">
402
- <tr valign="top">
403
- <th scope="row"><?php _e('Default event list format','dbem')?></th>
404
- <td><textarea name="dbem_event_list_item_format" id="dbem_event_list_item_format" rows="6" cols="60"><?php echo (get_option('dbem_event_list_item_format'));?></textarea><br/>
405
- <?php _e('The format of any events in a list.','dbem')?><br/>
406
- <?php _e('Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_VENUE</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_NOTES</code>. Use <code>#_LINKEDNAME</code> for the event name with a link to the given event page. Use #_URL to print the event URL and make your own customised links.','dbem')?>
407
- <?php _e('To insert date and time values, use <a href="http://www.php.net/manual/en/function.date.php">PHP time format characters</a> with a # symbol before them, i.e. #m. #M, #j, etc. ','dbem')?><br/>
408
- <?php _e('Use HTML tags as <code>li</code>, <code>br</code>, etc.','dbem')?></td>
409
- </tr>
410
- <tr valign="top">
411
- <th scope="row"><?php _e('Single event page title format','dbem');?></th>
412
- <td>
413
- <input name="dbem_event_page_title_format" type="text" id="dbem_event_page_title_format" style="width: 95%" value="<?php echo get_option('dbem_event_page_title_format'); ?>" size="45" /><br />
414
- <?php _e('The format of a single event page title.','dbem')?><br/>
415
- <?php _e('Follow the previous formatting instructions.','dbem')?>
416
- </td>
417
- </tr>
418
- <tr valign="top">
419
- <th scope="row"><?php _e('Default single event format','dbem')?></th>
420
- <td>
421
- <textarea name="dbem_single_event_format" id="dbem_single_event_format" rows="6" cols="60"><?php echo (get_option('dbem_single_event_format'));?></textarea><br/>
422
- <?php _e('The format of a single eventy page.','dbem')?><br/>
423
- <?php _e('Follow the previous formatting instructions.','dbem')?><br/>
424
- <?php _e('Use <code>#_MAP</code> to insert a map.','dbem')?>
425
- </td>
426
- </tr>
427
-
428
-
429
- <?php $list_events_page = get_option('dbem_list_events_page'); ?>
430
-
431
- <tr valign="top">
432
- <th scope="row"><?php _e('Show events page in lists?','dbem'); ?></th>
433
- <td>
434
- <input id="dbem_list_events_page" name="dbem_list_events_page" type="radio" value="1" <?php if($list_events_page) echo "checked='checked'"; ?> /><?php _e('Yes'); ?> <br />
435
- <input name="dbem_list_events_page" type="radio" value="0" <?php if(!$list_events_page) echo "checked='checked'"; ?> /><?php _e('No'); ?> <br />
436
- <?php _e('Check this option if you want the events page to appear together with other pages in pages lists.','dbem')?>
437
- </td>
438
- </tr>
439
-
440
-
441
-
442
-
443
- <tr valign="top">
444
- <th scope="row"><?php _e('Events page title','dbem'); ?></th>
445
- <td>
446
- <input name="dbem_events_page_title" type="text" id="dbem_events_page_title" style="width: 95%" value="<?php echo get_option('dbem_events_page_title'); ?>" size="45" /><br />
447
- <?php _e('The title on the multiple events page.','dbem')?>
448
- </td>
449
- </tr>
450
- <tr valign="top">
451
- <th scope="row"><?php _e('No events message','dbem');?></th>
452
- <td>
453
- <input name="dbem_no_events_message" type="text" id="dbem_no_events_message" style="width: 95%" value="<?php echo get_option('dbem_no_events_message'); ?>" size="45" /><br />
454
- <?php _e('The message displayed when no events are available.','dbem')?><br/>
455
- </td>
456
- </tr>
457
-
458
-
459
-
460
-
461
-
462
-
463
-
464
- <tr valign="top">
465
- <th scope="row"><?php _e('RSS main title','dbem'); ?></th>
466
- <td>
467
- <input name="dbem_rss_main_title" type="text" id="dbem_rss_main_title" style="width: 95%" value="<?php echo get_option('dbem_rss_main_title'); ?>" size="45" /><br />
468
- <?php _e('The main title of your RSS events feed.','dbem')?>
469
-
470
- </td>
471
- </tr> <tr valign="top">
472
- <th scope="row"><?php _e('RSS main description','dbem'); ?></th>
473
- <td>
474
- <input name="dbem_rss_main_description" type="text" id="dbem_rss_main_description" style="width: 95%" value="<?php echo get_option('dbem_rss_main_description'); ?>" size="45" /><br />
475
- <?php _e('The main description of your RSS events feed.','dbem')?>
476
-
477
- </td>
478
- </tr>
479
- <tr valign="top">
480
- <th scope="row"><?php _e('RSS title format','dbem'); ?></th>
481
- <td>
482
- <input name="dbem_rss_title_format" type="text" id="dbem_rss_title_format" style="width: 95%" value="<?php echo get_option('dbem_rss_title_format'); ?>" size="45" /><br />
483
- <?php _e('The format of the title of each item in the events RSS feed.','dbem')?>
484
-
485
- </td>
486
- </tr>
487
- <tr valign="top">
488
- <th scope="row"><?php _e('RSS description format','dbem'); ?></th>
489
- <td>
490
- <input name="dbem_rss_description_format" type="text" id="dbem_rss_description_format" style="width: 95%" value="<?php echo get_option('dbem_rss_description_format'); ?>" size="45" /><br />
491
- <?php _e('The format of the description of each item in the events RSS feed.','dbem')?>
492
- <?php _e('Follow the previous formatting instructions.','dbem')?><br/>
493
- </td>
494
- </tr>
495
-
496
-
497
-
498
-
499
-
500
-
501
- <?php $gmap_is_active = get_option('dbem_gmap_is_active'); ?>
502
-
503
- <tr valign="top">
504
- <th scope="row"><?php _e('Enable Google Maps integration?','dbem'); ?></th>
505
- <td>
506
- <input id="dbem_gmap_is_active_yes" name="dbem_gmap_is_active" type="radio" value="1" <?php if($gmap_is_active) echo "checked='checked'"; ?> /><?php _e('Yes'); ?> <br />
507
- <input name="dbem_gmap_is_active" type="radio" value="0" <?php if(!$gmap_is_active) echo "checked='checked'"; ?> /> <?php _e('No'); ?> <br />
508
- <?php _e('Check this option to enable Goggle Map integration.','dbem')?>
509
- </td>
510
- </tr>
511
-
512
- <tr valign="top">
513
- <th scope="row"><?php _e('Google Maps API Key','dbem'); ?></th>
514
- <td>
515
- <input name="dbem_gmap_key" type="text" id="dbem_gmap_key" style="width: 95%" value="<?php echo get_option('dbem_gmap_key'); ?>" size="45" /><br />
516
- <?php _e("To display Google Maps you need a Google Maps API key. Don't worry, it's free, you can get one", "dbem");?> <a href="http://code.google.com/apis/maps/signup.html"><?php _e("here",'dbem')?></a>.
517
- </td>
518
- </tr>
519
- <tr valign="top">
520
- <th scope="row"><?php _e('Map text format','dbem')?></th>
521
- <td><textarea name="dbem_map_text_format" id="dbem_map_text_format" rows="6" cols="60"><?php echo (get_option('dbem_map_text_format'));?></textarea><br/>
522
- <?php _e('The format the text appearing in the map cloud.','dbem')?><br/>
523
- <?php _e('Follow the previous formatting instructions.','dbem')?></td>
524
- </tr>
525
- </table>
526
- <p class="submit">
527
- <input type="submit" id="dbem_options_submit" name="Submit" value="<?php _e('Save Changes') ?>" />
528
- </p>
529
- <input type="hidden" name="action" value="update" />
530
- <input type="hidden" name="page_options" value="dbem_event_list_item_format,dbem_event_page_title_format,dbem_single_event_format,dbem_list_events_page,dbem_events_page_title, dbem_no_events_message, dbem_gmap_is_active, dbem_rss_main_title, dbem_rss_main_description, dbem_rss_title_format, dbem_rss_description_format, dbem_gmap_key, dbem_map_text_format" />
531
-
532
-
533
- </form>
534
- </div>
535
- <?php
536
-
537
-
538
  }
539
 
 
 
 
 
540
 
 
 
 
 
 
541
 
542
-
543
- //This is the content of the event page
544
- function dbem_events_page_content() {
545
-
546
- global $wpdb;
547
- if (isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '') {
548
- // single event page
549
- $event_ID=$_REQUEST['event_id'];
550
- $event= dbem_get_event($event_ID);
551
- $single_event_format = get_option('dbem_single_event_format');
552
- $page_body = dbem_replace_placeholders($single_event_format, $event);
553
- return $page_body;
554
- } else {
555
- // Multiple events page
556
- $stored_format = get_option('dbem_event_list_item_format');
557
- $events_body = dbem_get_events_list(10, "future", "ASC", $stored_format, $false);
558
- return $events_body;
559
 
 
 
 
 
 
 
560
  }
561
- }
562
-
563
- // filter function to call the event page when appropriate
564
- function dbem_filter_events_page($data) {
565
-
566
- // $table_name = $wpdb->prefix .TBNAME;
567
- // $start = strpos($data, DBEM_PAGE);
568
-
569
- $is_events_post = (get_the_ID() == get_option('dbem_events_page'));
570
- $events_page_id = get_option('dbem_events_page');
571
- if (is_page($events_page_id) && $is_events_post) {
572
- return dbem_events_page_content();
573
- } else {
574
- return $data;
575
- }
576
  }
577
- add_filter('the_content','dbem_filter_events_page');
578
-
579
- function dbem_events_page_title($data) {
580
- $events_page_id = get_option('dbem_events_page');
581
- $events_page = get_page($events_page_id);
582
- $events_page_title = $events_page->post_title;
583
- if (($data == $events_page_title) && (is_page($events_page_id))) {
584
- if (isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '') {
585
- // single event page
586
- $event_ID=$_REQUEST['event_id'];
587
- $event= dbem_get_event($event_ID);
588
- $stored_page_title_format = get_option('dbem_event_page_title_format');
589
- $page_title = dbem_replace_placeholders($stored_page_title_format, $event);
590
- return $page_title;
591
- } else {
592
- // Multiple events page
593
- $page_title = get_option('dbem_events_page_title');
594
- return $page_title;
595
 
596
- }
597
-
598
- } else {
599
- return $data;
600
- }
601
 
602
- }
603
- // to make sure that in pages lists the title is dbem_events_page_title, and not overwritten by the previous filter
604
- add_filter('the_title','dbem_events_page_title');
605
- add_filter('single_post_title','dbem_events_page_title');
606
-
607
- function dbem_filter_get_pages($data) {
608
- $output = array();
609
- $events_page_id = get_option('dbem_events_page');
610
- for ($i = 0; $i < count($data); ++$i) {
611
- if ($data[$i]->ID == $events_page_id) {
612
- $list_events_page = get_option('dbem_list_events_page');
613
- if($list_events_page) {
614
- $data[$i]->post_title = get_option('dbem_events_page_title')."&nbsp;";
615
- $output[] = $data[$i];
616
- }
617
- } else {
618
- $output[] = $data[$i];
619
- }
620
- }
621
- return $output;
622
- }
623
- add_filter('get_pages', 'dbem_filter_get_pages');
624
-
625
-
626
 
627
- //
628
- // TODO: ROBA NUOVA DA RIORDINARE
629
- // ADMIN CSS for debug
630
- function dbem_admin_css() {
631
- $css = "
632
- <style type='text/css'>
633
- .debug{
634
- color: green;
635
- background: #B7F98C;
636
- margin: 15px;
637
- padding: 10px;
638
- border: 1px solid #629948;
639
- }
640
- .switch-tab {
641
- background: #aaa;
642
- width: 100px;
643
- float: right;
644
- text-align: center;
645
- margin: 3px 1px 0 5px;
646
- padding: 2px;
647
- }
648
- .switch-tab a {
649
- color: #fff;
650
- text-decoration: none;
651
- }
652
- .switch-tab a:hover {
653
- color: #D54E21;
654
 
655
- }
656
- #events-pagination {
657
- text-align: center;
 
 
 
 
 
 
658
 
659
  }
660
- #events-pagination a {
661
- margin: 0 20px 0 20px;
662
- text-decoration: none;
663
- width: 80px;
664
- padding: 3px 0;
665
- background: #FAF4B7;
666
- border: 1px solid #ccc;
667
- border-top: none;
668
- }
669
- #new-event {
670
- float: left;
671
-
672
- }
673
- </style>";
674
- echo $css;
675
  }
676
 
677
- add_action('admin_print_scripts','dbem_admin_css');
678
-
679
- // exposed function, for theme makers
680
- function dbem_get_events_list($limit="3", $scope="future", $order="ASC", $format='', $display=true) {
681
- if ($scope == "")
682
- $scope = "future";
683
- if ($order != "DESC")
684
- $order = "ASC";
685
- if ($format == '')
686
- $format = get_option('dbem_event_list_item_format');
687
- $events = dbem_get_events($limit, $scope, $order);
688
- $output = "";
689
- if (!empty($events)) {
690
- foreach ($events as $event){
691
- // $localised_date = mysql2date("j M Y", $event->event_time);
692
 
693
-
694
-
695
- $output .= dbem_replace_placeholders($format, $event);
696
- }
697
- } else {
698
- $output = "<li class='dbem-no-events'>".get_option('dbem_no_events_message')."</li>";
 
 
 
 
 
 
699
  }
700
- if ($display)
701
- echo $output;
702
- else
703
- return $output;
704
- }
705
 
706
- function dbem_get_events_page($justurl=false) {
707
- $page_link = get_permalink(get_option("dbem_events_page")) ;
708
- if($justurl) {
709
- echo $page_link;
710
- } else {
711
- $page_title = get_option("dbem_events_page_title") ;
712
- echo "<a href='$page_link' title='$page_title'>$page_title</a>";
713
- }
714
 
715
- }
716
-
717
- // TEMPLATE TAGS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
718
 
719
- function dbem_are_events_available($scope="future") {
720
- if ($scope == "")
721
- $scope = "future";
722
- $events = dbem_get_events(1, $scope);
723
-
724
- if (empty($events))
725
- return FALSE;
726
- else
727
- return TRUE ;
728
  }
729
-
730
- // Returns true if the page in question is the events page
731
- function dbem_is_events_page() {
732
- $events_page_id = get_option('dbem_events_page');
733
- return is_page($events_page_id);
734
- }
735
 
736
- function dbem_is_single_event_page() {
737
- return (dbem_is_events_page() && (isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '')) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
738
  }
 
 
 
 
 
739
 
740
- function dbem_is_multiple_events_page() {
741
- return (dbem_is_events_page() && !(isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '')) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
742
  }
743
 
744
  function dbem_replace_placeholders($format, $event, $target="html") {
745
- $event_string = $format;
746
- preg_match_all("/#_?[A-Za-z]+/", $format, $placeholders);
747
  foreach($placeholders[0] as $result) {
 
748
  // matches alla fields placeholder
749
  if (preg_match('/#_MAP/', $result)) {
750
- $gmap_is_active = get_option('dbem_gmap_is_active');
751
- if ($gmap_is_active) {
752
- $map_div = "<div id='event-map' style=' background: green;'></div>" ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
753
  } else {
754
- $map_div = "";
755
  }
756
- $event_string = str_replace($result, $map_div , $event_string );
757
  }
758
  if (preg_match('/#_LINKEDNAME/', $result)) {
759
  $events_page_id = get_option('dbem_events_page');
@@ -762,20 +493,21 @@ function dbem_replace_placeholders($format, $event, $target="html") {
762
  $joiner = "&amp;";
763
  else
764
  $joiner = "?";
765
- $event_string = str_replace($result, "<a href='".get_permalink($events_page_id).$joiner."event_id=$event->event_id' title='$event->event_name'>$event->event_name</a>" , $event_string );
766
  }
767
- if (preg_match('/#_URL/', $result)) {
768
  $events_page_id = get_option('dbem_events_page');
769
  $event_page_link = get_permalink($events_page_id);
770
  if (stristr($event_page_link, "?"))
771
  $joiner = "&amp;";
772
  else
773
  $joiner = "?";
774
- $event_string = str_replace($result, get_permalink($events_page_id).$joiner."event_id=$event->event_id" , $event_string );
775
  }
776
- if (preg_match('/#_(NAME|VENUE|ADDRESS|TOWN|PROVINCE|NOTES)/', $result)) {
777
- $field = "event_".ltrim(strtolower($result), "#_");
778
- $field_value = $event->{$field};
 
779
  if ($field == "event_notes") {
780
  if ($target == "html")
781
  $field_value = apply_filters('dbem_notes', $field_value);
@@ -791,642 +523,99 @@ function dbem_replace_placeholders($format, $event, $target="html") {
791
  $field_value = apply_filters('dbem_general_rss', $field_value);
792
  }
793
  $event_string = str_replace($result, $field_value , $event_string );
794
- }
795
- // matches all PHP time placeholders
796
- if (preg_match('/#[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]/', $result)) {
797
- $event_string = str_replace($result, mysql2date(ltrim($result, "#"), $event->event_time),$event_string );
798
- }
799
- }
800
- return $event_string;
801
-
802
- }
803
- // main function querying the database event table
804
- function dbem_get_events($limit="",$scope="future",$order="ASC", $offset="") {
805
- global $wpdb;
806
-
807
- if ($limit != "")
808
- $limit = "LIMIT $limit";
809
- if ($offset != "")
810
- $offset = "OFFSET $offset";
811
-
812
- if (($scope != "past") && ($scope !="all"))
813
- $scope = "future";
814
-
815
- $timestamp = time();
816
- $date_time_array = getdate($timestamp);
817
- $hours = $date_time_array['hours'];
818
- $minutes = $date_time_array['minutes'];
819
- $seconds = $date_time_array['seconds'];
820
- $month = $date_time_array['mon'];
821
- $day = $date_time_array['mday'];
822
- $year = $date_time_array['year'];
823
- $today = strftime('%Y-%m-%d 00:00:00', mktime($hours,$minutes,$seconds,$month,$day,$year));
824
-
825
-
826
-
827
-
828
- if ($scope == "future")
829
- $temporal_condition = "WHERE event_time >= '$today'" ;
830
- if ($scope == "past")
831
- $temporal_condition = "WHERE event_time < '$today'" ;
832
- if ($scope == "all")
833
- $temporal_condition = "";
834
-
835
- $sql = "SELECT event_id,
836
- event_name,
837
- event_venue,
838
- event_address,
839
- event_town,
840
- event_province,
841
- DATE_FORMAT(event_time, '%e') AS 'event_day',
842
- DATE_FORMAT(event_time, '%Y') AS 'event_year',
843
- DATE_FORMAT(event_time, '%k') AS 'event_hh',
844
- DATE_FORMAT(event_time, '%i') AS 'event_mm',
845
- event_time,
846
- event_latitude,
847
- event_longitude,
848
- event_notes
849
- FROM ".$wpdb->prefix."events
850
- $temporal_condition
851
- ORDER BY event_time $order
852
- $limit
853
- $offset";
854
-
855
-
856
- $events = $wpdb->get_results($sql);
857
-
858
- return $events;
859
- }
860
- function dbem_get_event($event_id) {
861
- global $wpdb;
862
- $sql = "SELECT event_id,
863
- event_name,
864
- event_venue,
865
- event_address,
866
- event_town,
867
- event_province,
868
- DATE_FORMAT(event_time, '%e') AS 'event_day',
869
- DATE_FORMAT(event_time, '%Y') AS 'event_year',
870
- DATE_FORMAT(event_time, '%k') AS 'event_hh',
871
- DATE_FORMAT(event_time, '%i') AS 'event_mm',
872
- event_time,
873
- event_latitude,
874
- event_longitude,
875
- event_notes
876
- FROM ".$wpdb->prefix."events
877
- WHERE event_id = $event_id";
878
-
879
-
880
- $event = $wpdb->get_row($sql);
881
-
882
- return $event;
883
- }
884
- function dbem_events_table($events, $limit, $title) {
885
-
886
-
887
- if (isset($_GET['scope']))
888
- $scope = $_GET['scope'];
889
- else
890
- $scope = "future";
891
- if (($scope != "past") && ($scope != "all"))
892
- $scope = "future";
893
- $events_count = count(dbem_get_events("",$scope));
894
-
895
- if (isset($_GET['offset']))
896
- $offset = $_GET['offset'];
897
-
898
-
899
- ?>
900
- <div class="wrap">
901
-
902
- <h2><?php echo $title; ?></h2>
903
- <div id='new-event' class='switch-tab'><a href="<?php bloginfo('wpurl')?>/wp-admin/edit.php?page=eventmanager.php&amp;action=edit_event"><?php _e('New Event ...', 'dbem');?></a></div>
904
- <?php
905
-
906
- $link = array();
907
- $link['past'] = "<a href='".get_bloginfo('url')."/wp-admin/edit.php?page=eventmanager.php&amp;scope=past&amp;order=desc'>".__('Past events','dbem')."</a>";
908
- $link['all'] = " <a href='".get_bloginfo('url')."/wp-admin/edit.php?page=eventmanager.php&amp;scope=all&amp;order=desc'>".__('All events','dbem')."</a>";
909
- $link['future'] = " <a href='".get_bloginfo('url')."/wp-admin/edit.php?page=eventmanager.php&amp;scope=future'>".__('Future events','dbem')."</a>";
910
- foreach ($link as $key => $value) {
911
- if ($key != $scope)
912
- echo "<div class='switch-tab'>".$link[$key]."</div>";
913
- } ?>
914
 
915
-
916
- <table class="widefat">
917
- <thead>
918
- <tr>
919
- <th><?php _e('ID', 'dbem');?></th>
920
- <th><?php _e('Name', 'dbem');?></th>
921
- <th><?php _e('Venue', 'dbem');?></th>
922
- <th><?php _e('Town', 'dbem');?></th>
923
- <th><?php _e('Address', 'dbem');?></th>
924
- <th><?php _e('Date', 'dbem');?></th>
925
- <th><?php _e('Time', 'dbem');?></th>
926
- <?php if (false) { ?>
927
- <th><?php _e('Latitude', 'dbem');?></th>
928
- <th><?php _e('Longitude', 'dbem');?></th>
929
- <?php } ?>
930
- <th colspan="2"><?php _e('Actions', 'dbem');?></th>
931
- </tr>
932
- </thead>
933
- <tbody>
934
- <?php
935
- $i =1;
936
- foreach ($events as $event){
937
- $class = ($i % 2) ? ' class="alternate"' : '';
938
- $month = mysql2date('M', $event->event_time);
939
- $weekday = mysql2date('D', $event->event_time);
940
- $style = "";
941
-
942
- $timestamp = time();
943
- $date_time_array = getdate($timestamp);
944
- $this_hours = $date_time_array['hours'];
945
- $this_minutes = $date_time_array['minutes'];
946
- $this_seconds = $date_time_array['seconds'];
947
- $this_month = $date_time_array['mon'];
948
- $this_day = $date_time_array['mday'];
949
- $this_year = $date_time_array['year'];
950
- $today = strftime('%Y-%m-%d 00:00:00', mktime($this_hours,$this_minutes,$this_seconds,$this_month,$this_day,$this_year));
951
-
952
 
953
- if ($event->event_time < $today )
954
- $style= "style ='background-color: #FADDB7;'";
955
- ?>
956
- <tr <?php echo"$class $style"; ?> >
957
- <td>
958
- <strong><?php echo "$event->event_id"; ?></strong>
959
- </td>
960
- <td>
961
- <?php echo "$event->event_name"; ?>
962
- </td>
963
- <td>
964
- <?php echo "$event->event_venue"; ?>
965
- </td>
966
- <td>
967
- <?php
968
- echo "$event->event_town";
969
- if (isset($event->event_province)) {
970
- echo " ($event->event_province)";
971
- }
972
- ?>
973
- </td>
974
- <td>
975
- <?php echo "$event->event_address"; ?>
976
- </td>
977
- <td>
978
- <?php echo "$weekday $event->event_day $month $event->event_year"; ?>
979
- </td>
980
- <td>
981
- <?php echo "$event->event_hh : $event->event_mm"; ?>
982
- </td>
983
- <?php if (false) { ?>
984
- <td>
985
- <?php echo "$event->event_latitude"; ?>
986
- </td>
987
- <td>
988
- <?php echo "$event->event_longitude"; ?>
989
- </td>
990
- <?php } ?>
991
- <td><a class="edit" href="<?php bloginfo('wpurl')?>/wp-admin/edit.php?page=eventmanager.php&amp;action=edit_event&amp;event_id=<?php echo "$event->event_id"?>"><?php _e('Edit'); ?></a></td>
992
- <td><a class="delete" href="<?php bloginfo('wpurl')?>/wp-admin/edit.php?page=eventmanager.php&amp;action=delete_event&amp;event_id=<?php echo "$event->event_id" ?>" onclick="return confirm('<?php _e('Are you sure?','dbem'); ?>');"><?php _e('Delete'); ?></a></td>
993
- <?php
994
- echo'</tr>';
995
- $i++;
996
  }
997
- ?>
998
-
999
- </tbody>
1000
- </table>
1001
- <?php
1002
- if ($events_count > $limit) {
1003
- $backward = $offset + $limit;
1004
- $forward = $offset - $limit;
1005
- if (DEBUG)
1006
- echo "COUNT = $count BACKWARD = $backward FORWARD = $forward<br> -- OFFSET = $offset" ;
1007
- echo "<div id='events-pagination'> ";
1008
- if ($backward < $events_count)
1009
- echo "<a style='float: left' href='".get_bloginfo('url')."/wp-admin/edit.php?page=eventmanager.php&amp;scope=$scope&offset=$backward'>&lt;&lt;</a>" ;
1010
- if ($forward >= 0)
1011
- echo "<a style='float: right' href='".get_bloginfo('url')."/wp-admin/edit.php?page=eventmanager.php&amp;scope=$scope&offset=$forward'>&gt;&gt;</a>";
1012
- echo "</div>" ;
1013
  }
1014
- ?>
1015
-
1016
- </div>
1017
- <?php
1018
- }
1019
- function dbem_event_form($event, $title, $element) {
1020
- ?>
1021
- <form id="eventForm" method="post" action="edit.php?page=eventmanager.php&amp;action=update_event&amp;event_id=<?php echo "$element"?>">
1022
- <div class="wrap">
1023
- <h2><?php echo $title; ?></h2>
1024
- <div id="poststuff">
1025
- <div id="postbody">
1026
- <div id="event_name" class="stuffbox">
1027
- <h3><?php _e('Name','dbem'); ?></h3>
1028
- <div class="inside">
1029
- <input type="text" name="event_name" value="<?php echo $event['event_name'] ?>" /><br/>
1030
- <?php _e('The event name. Example: Birthday party', 'dbem') ?>
1031
- </div>
1032
- </div>
1033
- <div id="event_day" class="stuffbox">
1034
- <h3><?php _e('Day and Time','dbem'); ?></h3>
1035
- <div class="inside">
1036
- <input type="text" size="3" maxlength="2" name="event_day" value="<?php echo $event['event_day']?>" /> /
1037
- <input type="text" size="3" maxlength="2" name="event_month" value="<?php echo $event['event_month']?>" /> /
1038
- <input type="text" size="5" maxlength="4" name="event_year" value="<?php echo $event['event_year'] ?>" /> - <input type="text" size="3" maxlength="2" name="event_hh" value="<?php echo $event['event_hh'] ?>" /> : <input type="text" size="3" maxlength="2" name="event_mm" value="<?php echo $event['event_mm'] ?>" /><br/>
1039
- <!-- <input id="event_date" type="text" name="event_date" value="<?php //echo $event['event_date'] ?>" /><br/> -->
1040
- <?php _e('The event day and time. Example: 21/11/2009 - 21:30', 'dbem') ?>
1041
- </div>
1042
- </div>
1043
- <?php
1044
- $gmap_is_active = get_option('dbem_gmap_is_active');
1045
- if ($gmap_is_active) {
1046
- echo "<div id='map-not-found' style='width: 450px; float: right; font-size: 140%; text-align: center; margin-top: 100px; display: hide'><p>".__('Map not found')."</p></div>";
1047
- echo "<div id='event-map' style='width: 450px; height: 300px; background: green; float: right; display: hide; margin-right:8px'></div>";
1048
- }
1049
- ?>
1050
- <div id="event_town" class="stuffbox">
1051
- <h3><?php _e('Town','dbem'); ?></h3>
1052
- <div class="inside">
1053
- <input id="town-input" type="text" name="event_town" value="<?php echo $event['event_town']?>" /><br/>
1054
- <?php _e('The event town. Example: Verona. If you\' using the Google Map integration and want to avoid geotagging ambiguities include the country as well. Example: Verona, Italy', 'dbem') ?>
1055
- </div>
1056
- </div>
1057
- <div id="event_venue" class="stuffbox">
1058
- <h3><?php _e('Venue','dbem'); ?></h3>
1059
- <div class="inside">
1060
- <input id="venue-input" type="text" name="event_venue" value="<?php echo $event['event_venue']?>" /><br/>
1061
- <?php _e('The venue where the event takes place. Example: Arena', 'dbem') ?>
1062
- </div>
1063
- </div>
1064
- <div id="event_address" class="stuffbox">
1065
- <h3><?php _e('Address','dbem'); ?></h3>
1066
- <div class="inside">
1067
- <input id="address-input" type="text" name="event_address" value="<?php echo $event['event_address']; ?>" /><br/>
1068
- <?php _e('The address of the venue. Example: Via Mazzini 22', 'dbem') ?>
1069
- </div>
1070
- </div>
1071
- <div id="event_notes" class="postbox closed">
1072
- <h3><?php _e('Notes','dbem'); ?></h3>
1073
- <div class="inside">
1074
- <textarea name="event_notes" rows="8" cols="60"><?php echo $event['event_notes']; ?></textarea><br/>
1075
- <?php _e('Notes about the event', 'dbem') ?>
1076
- </div>
1077
- </div>
1078
- </div>
1079
- </div>
1080
- <p class="submit"><input type="submit" name="events_update" value="<?php _e('Submit Event','dbem'); ?> &raquo;" /></p>
1081
- </div>
1082
- </form>
1083
- <?php
1084
- }
1085
-
1086
- function dbem_validate_event($event) {
1087
- // TODO decide which fields are required
1088
- // Implement type check for dates, etc
1089
- $required_fields = array('event_name');
1090
- foreach ($required_fields as $field) {
1091
- if ($event[$field] == "" ) {
1092
- return "$field missing!";
1093
- }
1094
- }
1095
- if (checkdate ((int)$event['event_month'], (int)$event['event_day'], (int)$event['event_year']) == FALSE) {
1096
- return "invalid date!" ;
1097
- }
1098
- $time = $event['event_hh'].":".$event['event_mm'];
1099
- if ($required_fields['event_hh'] && !preg_match ("/([01]\d|2[0-3])(:[0-5]\d){0,2}/", $time )) {
1100
- //TODO sistema validate time
1101
- }
1102
- return "OK";
1103
-
1104
- }
1105
-
1106
-
1107
- // Enqueing jQuery script to make sure it's loaded
1108
- function dbem_enque_scripts(){
1109
- wp_enqueue_script( 'jquery' );
1110
- }
1111
- add_action ('template_redirect', 'dbem_enque_scripts');
1112
-
1113
- // General script to make sure hidden fields are shown when containing data
1114
- function dbem_admin_general_script(){ ?>
1115
-
1116
- <script type="text/javascript">
1117
- //<![CDATA[
1118
- // TODO: make more general, to support also latitude and longitude (when added)
1119
- jQuery(document).ready( function() {
1120
- jQuery('.postbox h3').prepend('<a class="togbox">+</a> ');
1121
- if(jQuery("textarea[@name=event_notes]").val()!="") {
1122
- jQuery("textarea[@name=event_notes]").parent().parent().removeClass('closed');
1123
- }
1124
- jQuery('#event_notes h3').click( function() {
1125
- jQuery(jQuery(this).parent().get(0)).toggleClass('closed');
1126
- });
1127
-
1128
-
1129
- });
1130
- //]]>
1131
- </script>
1132
 
1133
- <?php
1134
- }
1135
- add_action ('admin_head', 'dbem_admin_general_script');
1136
-
1137
-
1138
- // Google maps implementation
1139
- function dbem_map_script() {
1140
- $gmap_is_active = get_option('dbem_gmap_is_active');
1141
- if ($gmap_is_active) {
1142
- if (strpos(get_option('dbem_single_event_format'), "#_MAP")) { // loading the script is useless unless #_MAP is in the format
1143
- if (isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '') {
1144
- // single event page
1145
- $event_ID=$_REQUEST['event_id'];
1146
- $event = dbem_get_event($event_ID);
1147
- if ($event->event_town != '') {
1148
- $gmap_key = get_option('dbem_gmap_key');
1149
- if($event->event_address != "") {
1150
- $search_key = "$event->event_address, $event->event_town";
1151
- } else {
1152
- $search_key = "$event->event_venue, $event->event_town";
1153
- }
1154
- $map_text_format = get_option('dbem_map_text_format');
1155
- $map_text = dbem_replace_placeholders($map_text_format, $event, "map");
1156
-
1157
- ?>
1158
-
1159
-
1160
- <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=<?php echo $gmap_key;?>" type="text/javascript"></script>
1161
- <script type="text/javascript">
1162
- //<![CDATA[
1163
- $j=jQuery.noConflict();
1164
- function loadMap() {
1165
- if (GBrowserIsCompatible()) {
1166
- var map = new GMap2(document.getElementById("event-map"));
1167
- var mapTypeControl = new GLargeMapControl();
1168
- var topRight = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10,10));
1169
- map.addControl(mapTypeControl, topRight);
1170
-
1171
- // map.addControl(new GLargeMapControl());
1172
- //map.setCenter(new GLatLng(37.4419, -122.1419), 13);
1173
- var geocoder = new GClientGeocoder();
1174
- var address = "<?php echo $search_key ?>" ;
1175
- geocoder.getLatLng(
1176
- address,
1177
- function(point) {
1178
- if (!point) {
1179
- $j("#event-map").hide();
1180
- } else {
1181
- mapCenter= new GLatLng(point.lat()+0.01, point.lng()+0.005);
1182
- map.setCenter(mapCenter, 13);
1183
- var marker = new GMarker(point);
1184
- map.addOverlay(marker);
1185
- marker.openInfoWindowHtml('<?php echo $map_text;?>');
1186
- }
1187
- }
1188
- );
1189
- }
1190
- }
1191
-
1192
- $j(document).ready(function() {
1193
- if ($j("#event-map").length > 0 ) {
1194
- loadMap();
1195
- }
1196
-
1197
- });
1198
- $j(document).unload(function() {
1199
- if ($j("#event-map").length > 0 ) {
1200
- GUnload();
1201
- }
1202
- });
1203
- //]]>
1204
- </script>
1205
- <style type="text/css">
1206
- #event-map {
1207
- width: 450px;
1208
- height: 300px;
1209
- }
1210
- #event-map img {
1211
- background: transparent;
1212
- }
1213
- </style>
1214
- <?php
1215
- }
1216
- }
1217
  }
1218
- }
1219
- }
1220
- add_action ('wp_head', 'dbem_map_script');
1221
-
1222
- function dbem_admin_map_script() {
1223
- if (isset($_REQUEST['event_id']) && $_REQUEST['event_id'] != '') {
1224
- if (!(isset($_REQUEST['action']) && $_REQUEST['action'] == 'delete_event')) {
1225
- // single event page
1226
- $event_ID=$_REQUEST['event_id'];
1227
- $event = dbem_get_event($event_ID);
1228
- if ($event->event_town != '') {
1229
- $gmap_key = get_option('dbem_gmap_key');
1230
- if($event->event_address != "") {
1231
- $search_key = "$event->event_address, $event->event_town";
1232
- } else {
1233
- $search_key = "$event->event_venue, $event->event_town";
1234
- }
1235
-
1236
- ?>
1237
- <style type="text/css">
1238
- div#event_town, div#event_address, div#event_venue {
1239
- width: 480px;
1240
- }
1241
- </style>
1242
- <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=<?php echo $gmap_key;?>" type="text/javascript"></script>
1243
- <script type="text/javascript">
1244
- //<![CDATA[
1245
- $j=jQuery.noConflict();
1246
 
1247
- function loadMap(venue, town, address) {
1248
- if (GBrowserIsCompatible()) {
1249
- var map = new GMap2(document.getElementById("event-map"));
1250
- // map.addControl(new GScaleControl());
1251
- //map.setCenter(new GLatLng(37.4419, -122.1419), 13);
1252
- var geocoder = new GClientGeocoder();
1253
- if (address !="") {
1254
- searchKey = address + ", " + town;
1255
- } else {
1256
- searchKey = venue + ", " * town;
1257
- }
1258
-
1259
- var search = "<?php echo $search_key ?>" ;
1260
- geocoder.getLatLng(
1261
- searchKey,
1262
- function(point) {
1263
- if (!point) {
1264
- $j("#event-map").hide();
1265
- $j('#map-not-found').show();
1266
- } else {
1267
- mapCenter= new GLatLng(point.lat()+0.01, point.lng()+0.005);
1268
- map.setCenter(mapCenter, 13);
1269
- var marker = new GMarker(point);
1270
- map.addOverlay(marker);
1271
- marker.openInfoWindowHtml('<strong>' + venue +'</strong><p>' + address + '</p><p>' + town + '</p>');
1272
- $j("#event-map").show();
1273
- $j('#map-not-found').hide();
1274
- }
1275
- }
1276
- );
1277
- // map.addControl(new GSmallMapControl());
1278
- // map.addControl(new GMapTypeControl());
1279
-
1280
- }
1281
- }
1282
-
1283
- $j(document).ready(function() {
1284
- eventVenue = $j("#venue-input").val();
1285
-
1286
- eventTown = $j("#town-input").val();
1287
- eventAddress = $j("#address-input").val();
1288
-
1289
- loadMap(eventVenue, eventTown, eventAddress);
1290
-
1291
- $j("#venue-input").blur(function(){
1292
- newEventVenue = $j("#venue-input").val();
1293
- if (newEventVenue !=eventVenue) {
1294
- loadMap(newEventVenue, eventTown, eventAddress);
1295
- eventVenue = newEventVenue;
1296
-
1297
- }
1298
- });
1299
- $j("#town-input").blur(function(){
1300
- newEventTown = $j("#town-input").val();
1301
- if (newEventTown !=eventTown) {
1302
- loadMap(eventVenue, newEventTown, eventAddress);
1303
- eventTown = newEventTown;
1304
- }
1305
- });
1306
- $j("#address-input").blur(function(){
1307
- newEventAddress = $j("#address-input").val();
1308
- if (newEventAddress != eventAddress) {
1309
- loadMap(eventVenue, eventTown, newEventAddress);
1310
- eventAddress = newEventAddress;
1311
- }
1312
- });
1313
-
1314
-
1315
-
1316
- });
1317
- $j(document).unload(function() {
1318
- GUnload();
1319
- });
1320
- //]]>
1321
- </script>
1322
- <?php
1323
- }
1324
- }
1325
- }
1326
- }
1327
- $gmap_is_active = get_option('dbem_gmap_is_active');
1328
- if ($gmap_is_active)
1329
- add_action ('admin_head', 'dbem_admin_map_script');
1330
-
1331
- // Script to validate map options
1332
- function dbem_admin_options_script() {
1333
- if (isset($_REQUEST['page']) && $_REQUEST['page'] == 'events-manager/events-manager.php') {
1334
- ?>
1335
- <script type="text/javascript">
1336
- //<![CDATA[
1337
- $j=jQuery.noConflict();
1338
 
1339
- $j(document).ready(function() {
1340
- // users cannot enable Googlr Maps without an api key
1341
- function verifyOptionsForm(){
1342
- var gmap_is_active = $j("input[@name=dbem_gmap_is_active]:checked").val();
1343
- var gmap_key = $j("input[@name=dbem_gmap_key]").val();
1344
- if(gmap_is_active == '1' && (gmap_key == '')){
1345
- alert("<?php _e('You cannot enable Google Maps integration without setting an appropriate API key.');?>");
1346
- $j("input[@name='dbem_gmap_is_active']:nth(1)").attr("checked","checked");
1347
-
1348
- return false;
1349
- } else {
1350
- return true;
1351
- }
1352
- }
1353
-
1354
- $j('#dbem_options_form').bind("submit", verifyOptionsForm);
1355
-
1356
-
1357
- });
1358
-
1359
 
1360
- //]]>
1361
- </script>
1362
-
1363
- <?php
1364
 
 
1365
  }
 
1366
 
1367
  }
1368
- add_action ('admin_head', 'dbem_admin_options_script');
1369
-
1370
- function dbem_rss_link($justurl=false) {
1371
- $rss_title = get_option('dbem_events_page_title');
1372
- $url = get_bloginfo('url')."/?dbem_rss=main";
1373
- $link = "<a href='$url'>RSS</a>";
1374
- if ($justurl)
1375
- echo $url;
1376
- else
1377
- echo $link;
1378
- }
1379
 
1380
- function dbem_rss() {
1381
- if (isset($_REQUEST['dbem_rss']) && $_REQUEST['dbem_rss'] == 'main') {
1382
- header("Content-type: text/xml");
1383
- echo "<?xml version='1.0'?>\n";
1384
-
1385
- $events_page_id = get_option('dbem_events_page');
1386
- $events_page_link = get_permalink($events_page_id);
1387
- if (stristr($events_page_link, "?"))
1388
- $joiner = "&amp;";
1389
- else
1390
- $joiner = "?";
1391
-
1392
-
1393
- ?>
1394
- <rss version="2.0">
1395
- <channel>
1396
- <title><?php echo get_option('dbem_rss_main_title');?></title>
1397
- <link><?php echo $events_page_link; ?></link>
1398
- <description><?php echo get_option('dbem_rss_main_description');?></description>
1399
- <docs>http://blogs.law.harvard.edu/tech/rss</docs>
1400
- <generator>Weblog Editor 2.0</generator>
1401
- <?php
1402
- $title_format = get_option('dbem_rss_title_format');
1403
- $description_format = str_replace(">","&gt;",str_replace("<","&lt;",get_option('dbem_rss_description_format')));
1404
- $events = dbem_get_events(5);
1405
- foreach ($events as $event) {
1406
- $title = dbem_replace_placeholders($title_format, $event, "rss");
1407
- $description = dbem_replace_placeholders($description_format, $event, "rss");
1408
- echo "<item>";
1409
- echo "<title>$title</title>\n";
1410
- echo "<link>$events_page_link".$joiner."event_id=$event->event_id</link>\n ";
1411
- echo "<description>$description </description>\n";
1412
- echo "</item>";
1413
- }
1414
- ?>
1415
-
1416
- </channel>
1417
- </rss>
1418
- </code>
1419
-
1420
- <?php
1421
- die();
1422
- }
1423
- }
1424
- add_action('init','dbem_rss');
1425
- function substitute_rss($data) {
1426
- if (isset($_REQUEST['event_id']))
1427
- return get_bloginfo('url')."/?dbem_rss=main";
1428
- else
1429
- return $data;
1430
  }
1431
- //add_filter('feed_link','substitute_rss')
1432
  ?>
1
  <?php
2
  /*
3
  Plugin Name: Events Manager
4
+ Version: 2.0b1
5
  Plugin URI: http://davidebenini.it/wordpress-plugins/events-manager/
6
+ Description: Manage events specifying precise spatial data (Location, Town, Province, etc).
7
  Author: Davide Benini
8
  Author URI: http://www.davidebenini.it/blog
9
  */
27
  */
28
 
29
  /*************************************************/
30
+
 
31
  // Setting constants
32
+ define('EVENTS_TBNAME','dbem_events'); //TABLE NAME
33
+ define('RECURRENCE_TBNAME','dbem_recurrence'); //TABLE NAME
34
+ define('LOCATIONS_TBNAME','dbem_locations'); //TABLE NAME
35
+ define('BOOKINGS_TBNAME','dbem_bookings'); //TABLE NAME
36
+ define('PEOPLE_TBNAME','dbem_people'); //TABLE NAME
37
+ define('BOOKING_PEOPLE_TBNAME','dbem_bookings_people'); //TABLE NAME
38
  define('DEFAULT_EVENT_PAGE_NAME', 'Events');
39
  define('DBEM_PAGE','<!--DBEM_EVENTS_PAGE-->'); //EVENTS PAGE
40
  define('MIN_CAPABILITY', 'edit_posts'); // Minimum user level to access calendars
43
  define('DEFAULT_SINGLE_EVENT_FORMAT', '<p>#j #M #Y - #H:#i</p><p>#_TOWN</p>');
44
  define('DEFAULT_EVENTS_PAGE_TITLE',__('Events','dbem') ) ;
45
  define('DEFAULT_EVENT_PAGE_TITLE_FORMAT', ' #_NAME');
46
+ define('DEFAULT_RSS_DESCRIPTION_FORMAT',"#j #M #y - #H:#i <br/>#_LOCATION <br/>#_ADDRESS <br/>#_TOWN");
47
  define('DEFAULT_RSS_TITLE_FORMAT',"#_NAME");
48
+ define('DEFAULT_MAP_TEXT_FORMAT', '<strong>#_LOCATION</strong><p>#_ADDRESS</p><p>#_TOWN</p>');
49
  define('DEFAULT_WIDGET_EVENT_LIST_ITEM_FORMAT','<li>#_LINKEDNAME<ul><li>#j #M #y</li><li>#_TOWN</li></ul></li>');
50
+ define('DEFAULT_NO_EVENTS_MESSAGE', __('No events', 'dbem'));
51
+ define('DEFAULT_SINGLE_LOCATION_FORMAT', '<p>#_ADDRESS</p><p>#_TOWN</p>');
52
+ define('DEFAULT_LOCATION_PAGE_TITLE_FORMAT', ' #_NAME');
53
+ define('DEFAULT_LOCATION_BALOON_FORMAT', "<strong>#_NAME</strong><br/>#_ADDRESS - #_TOWN<br/><a href='#_LOCATIONPAGEURL'>Details</a>");
54
+ define('DEFAULT_LOCATION_EVENT_LIST_ITEM_FORMAT', "<li>#_NAME - #j #M #Y - #H:#i</li>");
55
+ define('DEFAULT_LOCATION_NO_EVENTS_MESSAGE', __('<li>No events in this location</li>', 'dbem'));
56
+ define("IMAGE_UPLOAD_DIR", "wp-content/uploads/locations-pics");
57
+ define('DEFAULT_IMAGE_MAX_WIDTH', 700);
58
+ define('DEFAULT_IMAGE_MAX_HEIGHT', 700);
59
+ define('DEFAULT_IMAGE_MAX_SIZE', 204800);
60
  // DEBUG constant for developing
61
  // if you are hacking this plugin, set to TRUE, alog will show in admin pages
62
+ define('USE_FIREPHP', false);
63
+ // DEBUG constant for developing
64
+ // if you are hacking this plugin, set to TRUE, a log will show in admin pages
65
  define('DEBUG', false);
66
 
67
+ // if (DEBUG) {
68
+ // if (USE_FIREPHP) {
69
+ // require('FirePHPCore/fb.php');
70
+ // ob_start();
71
+ // fb('FirePHP activated');
72
+ // }
73
+ // }
74
+
75
+ // INCLUDES
76
+ include("dbem_events.php");
77
+ include("dbem_calendar.php");
78
+ include("dbem_widgets.php");
79
+ include("dbem_rsvp.php");
80
+ include("dbem_locations.php");
81
+ include("dbem_people.php");
82
+ include("dbem-recurrence.php");
83
+ include("dbem_UI_helpers.php");
84
+
85
+ require_once("phpmailer/dbem_phpmailer.php") ;
86
+ //require_once("phpmailer/language/phpmailer.lang-en.php") ;
87
+
88
+ // Localised date formats as in the jquery UI datepicker plugin
89
+ $localised_date_formats = array("am" => "dd.mm.yy","ar" => "dd/mm/yy", "bg" => "dd.mm.yy", "ca" => "mm/dd/yy", "cs" => "dd.mm.yy", "da" => "dd-mm-yy", "de" =>"dd.mm.yy", "es" => "dd/mm/yy", "en" => "mm/dd/yy", "fi" => "dd.mm.yy", "fr" => "dd/mm/yy", "he" => "dd/mm/yy", "hu" => "yy-mm-dd", "hy" => "dd.mm.yy", "id" => "dd/mm/yy", "is" => "dd/mm/yy", "it" => "dd/mm/yy", "ja" => "yy/mm/dd", "ko" => "yy-mm-dd", "lt" => "yy-mm-dd", "lv" => "dd-mm-yy", "nl" => "dd.mm.yy", "no" => "yy-mm-dd", "pl" => "yy-mm-dd", "pt" => "dd/mm/yy", "ro" => "mm/dd/yy", "ru" => "dd.mm.yy", "sk" => "dd.mm.yy", "sv" => "yy-mm-dd", "th" => "dd/mm/yy", "tr" => "dd.mm.yy", "ua" => "dd.mm.yy", "uk" => "dd.mm.yy", "us" => "mm/dd/yy", "CN" => "yy-mm-dd", "TW" => "yy/mm/dd");
90
+ //required fields
91
+ $required_fields = array('event_name');
92
+
93
+ load_plugin_textdomain('dbem', "/wp-content/plugins/events-manager/langs/");
94
+
95
  // To enable activation through the activate function
96
  register_activation_hook(__FILE__,'events-manager');
97
 
118
 
119
  add_filter('dbem_notes_map', 'convert_chars', 8);
120
  add_filter('dbem_notes_map', 'js_escape');
121
+
122
+
123
 
124
  /* Creating the wp_events table to store event data*/
125
  function dbem_install() {
126
+ // Creates the events table if necessary
127
+ dbem_create_events_table();
128
+ dbem_create_recurrence_table();
129
+ dbem_create_locations_table();
130
+ dbem_create_bookings_table();
131
+ dbem_create_people_table();
132
+ dbem_add_options();
133
+ dbem_migrate_old_events();
134
+ update_option('dbem_version', 2);
135
+
136
+ // Create events page if necessary
137
+ $events_page_id = get_option('dbem_events_page') ;
138
+ if ($events_page_id != "" ) {
139
+ query_posts("page_id=$events_page_id");
140
+ $count = 0;
141
+ while(have_posts()) { the_post();
142
+ $count++;
143
+ }
144
+ if ($count == 0)
145
+ dbem_create_events_page();
146
+ } else {
147
+ dbem_create_events_page();
148
+ }
149
+ // wp-content must be chmodded 777. Maybe just wp-content.
150
+ if(!file_exists("../".IMAGE_UPLOAD_DIR))
151
+ mkdir("../".IMAGE_UPLOAD_DIR, 0777);
152
+
153
+ }
154
+
155
+ function dbem_create_events_table() {
156
+
157
  global $wpdb, $user_level;
158
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
159
+
160
+ $old_table_name = $wpdb->prefix."events";
161
+ $table_name = $wpdb->prefix.EVENTS_TBNAME;
162
+
163
+ if(!($wpdb->get_var("SHOW TABLES LIKE '$old_table_name'") != $old_table_name)) {
164
+ // upgrading from previous versions
165
+
166
+ $sql = "ALTER TABLE $old_table_name RENAME $table_name;";
167
+ $wpdb->query($sql);
168
+
169
+ }
170
+
171
+
172
  if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
173
  // check the user is allowed to make changes
174
  // get_currentuserinfo();
179
  event_id mediumint(9) NOT NULL AUTO_INCREMENT,
180
  event_author mediumint(9) NOT NULL,
181
  event_name tinytext NOT NULL,
182
+ event_start_time time NOT NULL,
183
+ event_end_time time NOT NULL,
184
+ event_start_date date NOT NULL,
185
+ event_end_date date NULL,
 
186
  event_notes text NOT NULL,
187
+ event_rsvp bool NOT NULL DEFAULT 0,
188
+ event_seats tinyint,
189
+ event_contactperson_id mediumint(9) NULL,
190
+ location_id mediumint(9) NOT NULL,
191
+ recurrence_id mediumint(9) NULL,
192
  UNIQUE KEY (event_id)
193
  );";
194
+
195
  dbDelta($sql);
196
  //-------------- DEBUG CODE to insert a few events n the new table
197
  // get the current timestamp into an array
207
 
208
  // use mktime to recreate the unix timestamp
209
  // adding 19 hours to $hours
210
+ $in_one_week = strftime('%Y-%m-%d', mktime($hours,$minutes,$seconds,$month,$day+7,$year));
211
+ $in_four_weeks = strftime('%Y-%m-%d',mktime($hours,$minutes,$seconds,$month,$day+28,$year));
212
+ $in_one_year = strftime('%Y-%m-%d',mktime($hours,$minutes,$seconds,$month,$day,$year+1));
213
 
214
+ $wpdb->query("INSERT INTO ".$table_name." (event_name, event_start_date, event_start_time, event_end_time, location_id)
215
+ VALUES ('Orality in James Joyce Conference', '$in_one_week', '16:00:00', '18:00:00', 1)");
216
+ $wpdb->query("INSERT INTO ".$table_name." (event_name, event_start_date, event_start_time, event_end_time, location_id)
217
+ VALUES ('Traditional music session', '$in_four_weeks', '20:00:00', '22:00:00', 2)");
218
+ $wpdb->query("INSERT INTO ".$table_name." (event_name, event_start_date, event_start_time, event_end_time, location_id)
219
+ VALUES ('6 Nations, Italy VS Ireland', '$in_one_year','22:00:00', '24:00:00', 3)");
220
+ } else {
221
+ // eventual maybe_add_column() for later versions
222
+ maybe_add_column($table_name, 'event_start_date', "alter table $table_name add event_start_date date NOT NULL;");
223
+ maybe_add_column($table_name, 'event_end_date', "alter table $table_name add event_end_date date NULL;");
224
+ maybe_add_column($table_name, 'event_start_time', "alter table $table_name add event_start_time time NOT NULL;");
225
+ maybe_add_column($table_name, 'event_end_time', "alter table $table_name add event_end_time time NOT NULL;");
226
+ maybe_add_column($table_name, 'event_rsvp', "alter table $table_name add event_rsvp BOOL NOT NULL;");
227
+ maybe_add_column($table_name, 'event_seats', "alter table $table_name add event_seats tinyint NULL;");
228
+ maybe_add_column($table_name, 'location_id', "alter table $table_name add location_id mediumint(9) NOT NULL;");
229
+ maybe_add_column($table_name, 'recurrence_id', "alter table $table_name add recurrence_id mediumint(9) NULL;");
230
+ maybe_add_column($table_name, 'event_contactperson_id', "alter table $table_name add recurrence_id mediumint(9) NULL;");
231
  }
232
+ }
233
 
234
+ function dbem_create_recurrence_table() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
+ global $wpdb, $user_level;
237
+ $table_name = $wpdb->prefix.RECURRENCE_TBNAME;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
 
239
+ if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
240
+
241
+ $sql = "CREATE TABLE ".$table_name." (
242
+ recurrence_id mediumint(9) NOT NULL AUTO_INCREMENT,
243
+ recurrence_name tinytext NOT NULL,
244
+ recurrence_start_date date NOT NULL,
245
+ recurrence_end_date date NOT NULL,
246
+ recurrence_start_time time NOT NULL,
247
+ recurrence_end_time time NOT NULL,
248
+ recurrence_notes text NOT NULL,
249
+ location_id mediumint(9) NOT NULL,
250
+ recurrence_interval tinyint NOT NULL,
251
+ recurrence_freq tinytext NOT NULL,
252
+ recurrence_byday tinyint NOT NULL,
253
+ recurrence_byweekno tinyint NOT NULL,
254
+ event_contactperson_id mediumint(9) NULL,
255
+ UNIQUE KEY (recurrence_id)
256
+ );";
257
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
258
+ dbDelta($sql);
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  }
262
 
263
+ function dbem_create_locations_table() {
264
+
265
+ global $wpdb, $user_level;
266
+ $table_name = $wpdb->prefix.LOCATIONS_TBNAME;
267
 
268
+ if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
269
+
270
+ // check the user is allowed to make changes
271
+ // get_currentuserinfo();
272
+ // if ($user_level < 8) { return; }
273
 
274
+ // Creating the events table
275
+ $sql = "CREATE TABLE ".$table_name." (
276
+ location_id mediumint(9) NOT NULL AUTO_INCREMENT,
277
+ location_name tinytext NOT NULL,
278
+ location_address tinytext NOT NULL,
279
+ location_town tinytext NOT NULL,
280
+ location_province tinytext,
281
+ location_latitude float DEFAULT NULL,
282
+ location_longitude float DEFAULT NULL,
283
+ location_description text DEFAULT NULL,
284
+ UNIQUE KEY (location_id)
285
+ );";
286
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
287
+ dbDelta($sql);
 
 
 
288
 
289
+ $wpdb->query("INSERT INTO ".$table_name." (location_name, location_address, location_town, location_latitude, location_longitude)
290
+ VALUES ('Arts Millenium Building', 'Newcastle Road','Galway', 53.275, -9.06532)");
291
+ $wpdb->query("INSERT INTO ".$table_name." (location_name, location_address, location_town, location_latitude, location_longitude)
292
+ VALUES ('The Crane Bar', '2, Sea Road','Galway', 53.2692, -9.06151)");
293
+ $wpdb->query("INSERT INTO ".$table_name." (location_name, location_address, location_town, location_latitude, location_longitude)
294
+ VALUES ('Taaffes Bar', '19 Shop Street','Galway', 53.2725, -9.05321)");
295
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
 
298
+ function dbem_create_bookings_table() {
 
 
 
 
299
 
300
+ global $wpdb, $user_level;
301
+ $table_name = $wpdb->prefix.BOOKINGS_TBNAME;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
+ if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
 
305
+ $sql = "CREATE TABLE ".$table_name." (
306
+ booking_id mediumint(9) NOT NULL AUTO_INCREMENT,
307
+ event_id tinyint NOT NULL,
308
+ person_id tinyint NOT NULL,
309
+ booking_seats tinyint NOT NULL,
310
+ UNIQUE KEY (booking_id)
311
+ );";
312
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
313
+ dbDelta($sql);
314
 
315
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  }
317
 
318
+ function dbem_create_people_table() {
319
+
320
+ global $wpdb, $user_level;
321
+ $table_name = $wpdb->prefix.PEOPLE_TBNAME;
 
 
 
 
 
 
 
 
 
 
 
322
 
323
+ if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
324
+
325
+ $sql = "CREATE TABLE ".$table_name." (
326
+ person_id mediumint(9) NOT NULL AUTO_INCREMENT,
327
+ person_name tinytext NOT NULL,
328
+ person_email tinytext NOT NULL,
329
+ person_phone tinytext NOT NULL,
330
+ UNIQUE KEY (person_id)
331
+ );";
332
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
333
+ dbDelta($sql);
334
+
335
  }
336
+ }
 
 
 
 
337
 
338
+ function dbem_migrate_old_events() {
339
+ $version = get_option('dbem_version');
 
 
 
 
 
 
340
 
341
+ if ($version < 2) {
342
+ global $wpdb;
343
+
344
+ $events_table = $wpdb->prefix.EVENTS_TBNAME;
345
+ $sql = "SELECT event_id, event_time, event_venue, event_address, event_town FROM $events_table";
346
+ echo $sql;
347
+ $events = $wpdb->get_results($sql, ARRAY_A);
348
+ foreach($events as $event) {
349
+
350
+ // Migrating location data to the location table
351
+ $location = array('venue_name' => $event['event_venue'], 'location_address' => $event['event_address'], 'location_town' => $event['event_town']);
352
+ $related_location = dbem_get_identical_location($location);
353
+
354
+ if ($related_location) {
355
+ $event['location_id'] = $related_location['location_id'];
356
+ }
357
+ else {
358
+ $new_location = dbem_insert_location($location);
359
+ $event['location_id']= $new_location['location_id'];
360
+ }
361
+ // migrating event_time to event_start_date and event_start_time
362
+ $event['event_start_date'] = substr($event['event_time'],0,10);
363
+ $event['event_start_time'] = substr($event['event_time'],11,8);
364
+ $event['event_end_time'] = substr($event['event_time'],11,8);
365
+
366
+ $where = array('event_id' => $event['event_id']);
367
+ $wpdb->update($events_table, $event, $where);
368
+
369
 
370
+
371
+
372
+ }
373
+
374
+ }
 
 
 
 
375
  }
 
 
 
 
 
 
376
 
377
+ function dbem_add_options() {
378
+ $contact_person_email_body_localizable = __("#_RESPNAME (#_RESPEMAIL) will attend #_NAME on #m #d, #Y. He wants to reserve #_SPACES spaces.<br/> Now there are #_RESERVEDSPACES spaces reserved, #_AVAILABLESPACES are still available.<br/>Yours faithfully,<br/>Events Manager",'dbem') ;
379
+ $respondent_email_body_localizable = __("Dear #_RESPNAME, <br/>you have successfully reserved #_SPACES space/spaces for #_NAME.<br/>Yours faithfully,<br/> #_CONTACTPERSON",'dbem');
380
+
381
+ $dbem_options = array('dbem_event_list_item_format' => DEFAULT_EVENT_LIST_ITEM_FORMAT,
382
+ 'dbem_single_event_format' => DEFAULT_SINGLE_EVENT_FORMAT,
383
+ 'dbem_event_page_title_format' => DEFAULT_EVENT_PAGE_TITLE_FORMAT,
384
+ 'dbem_list_events_page' => 0,
385
+ 'dbem_events_page_title' => DEFAULT_EVENTS_PAGE_TITLE,
386
+ 'dbem_no_events_message' => __('No events','dbem'),
387
+ 'dbem_location_page_title_format' => DEFAULT_LOCATION_PAGE_TITLE_FORMAT,
388
+ 'dbem_location_baloon_format' => DEFAULT_LOCATION_BALOON_FORMAT,
389
+ 'dbem_location_event_list_item_format' => DEFAULT_LOCATION_EVENT_LIST_ITEM_FORMAT,
390
+ 'dbem_location_no_events_message' => DEFAULT_LOCATION_NO_EVENTS_MESSAGE,
391
+ 'dbem_single_location_format' => DEFAULT_SINGLE_LOCATION_FORMAT,
392
+ 'dbem_map_text_format' => DEFAULT_MAP_TEXT_FORMAT,
393
+ 'dbem_rss_main_title' => get_bloginfo('title')." - ".__('Events'),
394
+ 'dbem_rss_main_description' => get_bloginfo('description')." - ".__('Events'),
395
+ 'dbem_rss_description_format' => DEFAULT_RSS_DESCRIPTION_FORMAT,
396
+ 'dbem_rss_title_format' => DEFAULT_RSS_TITLE_FORMAT,
397
+ 'dbem_gmap_is_active'=>0,
398
+ 'dbem_gmap_key' => '',
399
+ 'dbem_default_contact_person' => 1,
400
+ 'dbem_rsvp_mail_notify_is_active' => 0 ,
401
+ 'dbem_contactperson_email_body' => __(str_replace("<br/>", "\n\r", $contact_person_email_body_localizable)),
402
+ 'dbem_respondent_email_body' => __(str_replace("<br>", "\n\r", $respondent_email_body_localizable)),
403
+ 'dbem_rsvp_mail_port' => 465,
404
+ 'dbem_smtp_host' => 'localhost',
405
+ 'dbem_mail_sender_name' => '',
406
+ 'dbem_rsvp_mail_send_method' => 'smtp',
407
+ 'dbem_rsvp_mail_SMTPAuth' => 1,
408
+ 'dbem_image_max_width' => DEFAULT_IMAGE_MAX_WIDTH,
409
+ 'dbem_image_max_height' => DEFAULT_IMAGE_MAX_HEIGHT,
410
+ 'dbem_image_max_size' => DEFAULT_IMAGE_MAX_SIZE,
411
+ 'dbem_hello_to_user' => 1,
412
+ 'dbem_version' => 1);
413
+
414
+ foreach($dbem_options as $key => $value)
415
+ dbem_add_option($key, $value);
416
+
417
  }
418
+ function dbem_add_option($key, $value) {
419
+ $option = get_option($key);
420
+ if (empty($option))
421
+ update_option($key, $value);
422
+ }
423
 
424
+ function dbem_create_events_page(){
425
+ echo "inserimento pagina";
426
+ global $wpdb,$current_user;
427
+ $page_name= DEFAULT_EVENT_PAGE_NAME;
428
+ $sql= "INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_type, post_content, post_title, post_name, post_modified, post_modified_gmt, comment_count) VALUES ($current_user->ID, '$now', '$now_gmt', 'page','CONTENTS', '$page_name', '".$wpdb->escape(__('Events','dbem'))."', '$now', '$now_gmt', '0')";
429
+ // echo($sql);
430
+ $wpdb->query($sql);
431
+
432
+ update_option('dbem_events_page', mysql_insert_id());
433
+ }
434
+
435
+ // Create the Manage Events and the Options submenus
436
+ add_action('admin_menu','dbem_create_events_submenu');
437
+ function dbem_create_events_submenu () {
438
+ if(function_exists('add_submenu_page')) {
439
+ add_object_page(__('Events', 'dbem'),__('Events', 'dbem'),MIN_CAPABILITY,__FILE__,dbem_events_subpanel, '../wp-content/plugins/events-manager/images/calendar-16.png');
440
+ // Add a submenu to the custom top-level menu:
441
+ add_submenu_page(__FILE__, __('Edit'),__('Edit'),MIN_CAPABILITY,__FILE__,dbem_events_subpanel);
442
+ add_submenu_page(__FILE__, __('Add new', 'dbem'), __('Add new','dbem'), MIN_CAPABILITY, 'new_event', "dbem_new_event_page");
443
+ add_submenu_page(__FILE__, "Locations", "Locations", MIN_CAPABILITY, 'locations', "dbem_locations_page");
444
+ add_submenu_page(__FILE__, "People", "People", MIN_CAPABILITY, 'people', "dbem_people_page");
445
+ //add_submenu_page(__FILE__, 'Test ', 'Test ', 8, 'test', 'dbem_recurrence_test');
446
+ add_submenu_page(__FILE__, 'Events Manager Settings','Settings', SETTING_CAPABILITY, "events-manager-options", dbem_options_subpanel);
447
+ }
448
  }
449
 
450
  function dbem_replace_placeholders($format, $event, $target="html") {
451
+ $event_string = $format;
452
+ preg_match_all("/#@?_?[A-Za-z]+/", $format, $placeholders);
453
  foreach($placeholders[0] as $result) {
454
+ // echo "RESULT: $result <br>";
455
  // matches alla fields placeholder
456
  if (preg_match('/#_MAP/', $result)) {
457
+ $location = dbem_get_location($event['location_id']);
458
+ $map_div = dbem_single_location_map($location);
459
+ $event_string = str_replace($result, $map_div , $event_string );
460
+
461
+ }
462
+ if (preg_match('/#_ADDBOOKINGFORM/', $result)) {
463
+ $rsvp_is_active = get_option('dbem_gmap_is_active');
464
+ if ($event['event_rsvp']) {
465
+ $rsvp_add_module .= dbem_add_booking_form();
466
+ } else {
467
+ $rsvp_add_module .= "";
468
+ }
469
+ $event_string = str_replace($result, $rsvp_add_module , $event_string );
470
+ }
471
+ if (preg_match('/#_REMOVEBOOKINGFORM/', $result)) {
472
+ $rsvp_is_active = get_option('dbem_gmap_is_active');
473
+ if ($event['event_rsvp']) {
474
+ $rsvp_delete_module .= dbem_delete_booking_form();
475
+ } else {
476
+ $rsvp_delete_module .= "";
477
+ }
478
+ $event_string = str_replace($result, $rsvp_delete_module , $event_string );
479
+ }
480
+ if (preg_match('/#_AVAILABLESEATS/', $result)) {
481
+ $rsvp_is_active = get_option('dbem_gmap_is_active');
482
+ if ($event['event_rsvp']) {
483
+ $availble_seats .= dbem_get_available_seats($event['event_id']);
484
  } else {
485
+ $availble_seats .= "";
486
  }
487
+ $event_string = str_replace($result, $availble_seats , $event_string );
488
  }
489
  if (preg_match('/#_LINKEDNAME/', $result)) {
490
  $events_page_id = get_option('dbem_events_page');
493
  $joiner = "&amp;";
494
  else
495
  $joiner = "?";
496
+ $event_string = str_replace($result, "<a href='".get_permalink($events_page_id).$joiner."event_id=".$event['event_id']."' title='".$event['event_name']."'>".$event['event_name']."</a>" , $event_string );
497
  }
498
+ if (preg_match('/#_EVENTPAGEURL/', $result)) {
499
  $events_page_id = get_option('dbem_events_page');
500
  $event_page_link = get_permalink($events_page_id);
501
  if (stristr($event_page_link, "?"))
502
  $joiner = "&amp;";
503
  else
504
  $joiner = "?";
505
+ $event_string = str_replace($result, get_permalink($events_page_id).$joiner."event_id=".$event['event_id'] , $event_string );
506
  }
507
+ if (preg_match('/#_(NAME|NOTES|SEATS)/', $result)) {
508
+ $field = "event_".ltrim(strtolower($result), "#_");
509
+ $field_value = $event[$field];
510
+
511
  if ($field == "event_notes") {
512
  if ($target == "html")
513
  $field_value = apply_filters('dbem_notes', $field_value);
523
  $field_value = apply_filters('dbem_general_rss', $field_value);
524
  }
525
  $event_string = str_replace($result, $field_value , $event_string );
526
+ }
527
+
528
+ if (preg_match('/#_(ADDRESS|TOWN|PROVINCE)/', $result)) {
529
+ $field = "location_".ltrim(strtolower($result), "#_");
530
+ $field_value = $event[$field];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
531
 
532
+ if ($field == "event_notes") {
533
+ if ($target == "html")
534
+ $field_value = apply_filters('dbem_notes', $field_value);
535
+ else
536
+ if ($target == "map")
537
+ $field_value = apply_filters('dbem_notes_map', $field_value);
538
+ else
539
+ $field_value = apply_filters('dbem_notes_rss', $field_value);
540
+ } else {
541
+ if ($target == "html")
542
+ $field_value = apply_filters('dbem_general', $field_value);
543
+ else
544
+ $field_value = apply_filters('dbem_general_rss', $field_value);
545
+ }
546
+ $event_string = str_replace($result, $field_value , $event_string );
547
+ }
548
+
549
+ if (preg_match('/#_(LOCATION)$/', $result)) {
550
+ $field = "location_name";
551
+ $field_value = $event[$field];
552
+ if ($target == "html")
553
+ $field_value = apply_filters('dbem_general', $field_value);
554
+ else
555
+ $field_value = apply_filters('dbem_general_rss', $field_value);
 
 
 
 
 
 
 
 
 
 
 
 
 
556
 
557
+ $event_string = str_replace($result, $field_value , $event_string );
558
+ }
559
+ if (preg_match('/#_CONTACTNAME$/', $result)) {
560
+ $event['event_contactperson_id'] ? $user_id = $event['event_contactperson_id'] : $user_id = get_option('dbem_default_contact_person');
561
+ $name = dbem_get_user_name($user_id);
562
+ $event_string = str_replace($result, $name, $event_string );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  }
564
+ if (preg_match('/#_CONTACTEMAIL$/', $result)) {
565
+ $event['event_contactperson_id'] ? $user_id = $event['event_contactperson_id'] : $user_id = get_option('dbem_default_contact_person');
566
+ $email = dbem_get_user_email($user_id);
567
+ $event_string = str_replace($result, dbem_ascii_encode($email), $event_string );
 
 
 
 
 
 
 
 
 
 
 
 
568
  }
569
+ if (preg_match('/#_CONTACTPHONE$/', $result)) {
570
+ $event['event_contactperson_id'] ? $user_id = $event['event_contactperson_id'] : $user_id = get_option('dbem_default_contact_person');
571
+ $phone = dbem_get_user_phone($user_id);
572
+ $event_string = str_replace($result, dbem_ascii_encode($phone), $event_string );
573
+ }
574
+ if (preg_match('/#_(IMAGE)/', $result)) {
575
+
576
+ if($event['location_image_url'] != '')
577
+ $location_image = "<img src='".$event['location_image_url']."' alt='".$event['location_name']."'/>";
578
+ else
579
+ $location_image = "";
580
+ $event_string = str_replace($result, $location_image , $event_string );
581
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
582
 
583
+ if (preg_match('/#_(LOCATIONPAGEURL)/', $result)) {
584
+ $venue_page_link = dbem_get_events_page(true, false)."&location_id=".$event['location_id'];
585
+ $event_string = str_replace($result, $venue_page_link , $event_string );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  }
587
+ // matches all PHP time placeholders for endtime
588
+ if (preg_match('/^#@[dDjlNSwzWFmMntLoYy]$/', $result)) {
589
+ $event_string = str_replace($result, mysql2date(ltrim($result, "#@"), $event['event_end_date']), $event_string );
590
+ }
591
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
592
 
593
+ // matches all PHP date placeholders
594
+ if (preg_match('/^#[dDjlNSwzWFmMntLoYy]$/', $result)) {
595
+ // echo "-inizio-";
596
+ $event_string = str_replace($result, mysql2date(ltrim($result, "#"), $event['event_start_date']),$event_string );
597
+ // echo $event_string;
598
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
 
600
+ // matches all PHP time placeholders
601
+ if (preg_match('/^#@[aABgGhHisueIOPTZcrU]$/', $result)) {
602
+ $event_string = str_replace($result, mysql2date(ltrim($result, "#@"), "0000-00-00 ".$event['event_end_time']),$event_string );
603
+ // echo $event_string;
604
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
 
606
+ if (preg_match('/^#[aABgGhHisueIOPTZcrU]$/', $result)) {
607
+ $event_string = str_replace($result, mysql2date(ltrim($result, "#"), "0000-00-00 ".$event['event_start_time']),$event_string );
608
+ // echo $event_string;
609
+ }
610
 
611
+
612
  }
613
+ return $event_string;
614
 
615
  }
 
 
 
 
 
 
 
 
 
 
 
616
 
617
+ function dbem_date_to_unix_time($date) {
618
+ $unix_time = mktime(0, 0, 0, substr($date,5,2), substr($date,8,2), substr($date,0,4));
619
+ return $unix_time;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
620
  }
 
621
  ?>
events_manager.css ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ table#dbem-bookings-table tfoot td.booking-result {
2
+ font-weight: bold;
3
+ background:#6D6D6D url(../../../wp-admin/images/menu-bits.gif) repeat-x scroll left top;
4
+ color: #eee;
5
+ }
6
+
7
+ table#dbem-bookings-table tfoot th {
8
+ text-align: right;
9
+ padding-right: 1em;
10
+
11
+ }
12
+
13
+ table.dbem-rsvp-form {
14
+ width: 80%;
15
+ }
16
+ table.dbem-rsvp-form th {
17
+ text-align: right;
18
+ width: 35%;
19
+ }
20
+
21
+ table.dbem-rsvp-form td {
22
+ padding-left: 1em;
23
+ text-align: left;
24
+ }
25
+
26
+ div.dbem-rsvp-message {
27
+ margin-bottom: 1em;
28
+ background-color: #FDDD73;
29
+ padding: 5px;
30
+ border: 2px solid #FF9100;
31
+ }
32
+
33
+ a.bookingdelbutton {
34
+ background: url("../../../wp-admin/images/xit.gif") no-repeat;
35
+ font-size: 11px;
36
+ text-indent: -9999px;
37
+ height: 10px;
38
+ width: 10px;
39
+ overflow:hidden;
40
+ position:absolute;
41
+
42
+ }
43
+ a.bookingdelbutton:hover {
44
+ background: url("../../../wp-admin/images/xit.gif") no-repeat -10px;
45
+
46
+ }
47
+ /* Printable stuff */
48
+ body#printable {
49
+ font-family: Gill Sans, Helvetica, Arial, sans-serif;
50
+ text-align: center;
51
+ }
52
+ body#printable #container {
53
+ margin: 0 auto;
54
+ width: 780px;
55
+ text-align: left;
56
+ }
57
+ table#bookings-table {
58
+ width: 600px;
59
+ border-spacing: 0px;
60
+
61
+ }
62
+ table#bookings-table td {
63
+ padding: 5px 0;
64
+ }
65
+ table#bookings-table td.seats-number {
66
+ text-align: right;
67
+ padding-right: 20px;
68
+ }
69
+ table#bookings-table th {
70
+ text-align: left;
71
+ margin-left: 5px;
72
+ }
73
+ table#bookings-table tr#booked-seats td{
74
+ border-top: 2px solid #999;
75
+ }
76
+
77
+ table#bookings-table td.total-label {
78
+ text-align: right;
79
+ }
80
+
81
+ table#bookings-table tr#booked-seats td.seats-number, table#bookings-table tr#available-seats td.seats-number {
82
+ font-weight: bold;
83
+ }
84
+
85
+ p#recurrence_warning {
86
+ border: 2px solid #FD0000;
87
+ background: #FF7146;
88
+ color: #fff;
89
+ font-weight: bold;
90
+ padding: 5px;
91
+ }
92
+ div#icon-events{
93
+ background:url('images/calendar-32.png') no-repeat center;
94
+ }
95
+
96
+ table#dbem-location-data th {
97
+ text-align: right;
98
+ width: 50px;
99
+ }
images/calendar-16.png ADDED
Binary file
images/calendar-32.png ADDED
Binary file
js/jquery-autocomplete/changelog.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 1.0.2
2
+ -----
3
+ * Fixed missing semicolon
4
+
5
+ 1.0.1
6
+ -----
7
+ * Fixed element creation (<ul> to <ul/> and <li> to </li>)
8
+ * Fixed ac_even class (was ac_event)
9
+ * Fixed bgiframe usage: now its really optional
10
+ * Removed the blur-on-return workaround, added a less obtrusive one only for Opera
11
+ * Fixed hold cursor keys: Opera needs keypress, everyone else keydown to scroll through result list when holding cursor key
12
+ * Updated package to jQuery 1.2.5, removing dimensions
13
+ * Fixed multiple-mustMatch: Remove only the last term when no match is found
14
+ * Fixed multiple without mustMatch: Don't select the last active when no match is found (on tab/return)
15
+ * Fixed multiple cursor position: Put cursor at end of input after selecting a value
16
+
17
+ 1.0
18
+ ---
19
+
20
+ * First release.
js/jquery-autocomplete/jquery.autocomplete.css ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .ac_results {
2
+ padding: 0px;
3
+ border: 1px solid black;
4
+ background-color: white;
5
+ overflow: hidden;
6
+ z-index: 99999;
7
+ }
8
+
9
+ .ac_results ul {
10
+ width: 100%;
11
+ list-style-position: outside;
12
+ list-style: none;
13
+ padding: 0;
14
+ margin: 0;
15
+ }
16
+
17
+ .ac_results li {
18
+ margin: 0px;
19
+ padding: 2px 5px;
20
+ cursor: default;
21
+ display: block;
22
+ /*
23
+ if width will be 100% horizontal scrollbar will apear
24
+ when scroll mode will be used
25
+ */
26
+ /*width: 100%;*/
27
+ font: menu;
28
+ font-size: 12px;
29
+ /*
30
+ it is very important, if line-height not setted or setted
31
+ in relative units scroll will be broken in firefox
32
+ */
33
+ line-height: 16px;
34
+ overflow: hidden;
35
+ }
36
+
37
+ .ac_loading {
38
+ background: white url('indicator.gif') right center no-repeat;
39
+ }
40
+
41
+ .ac_odd {
42
+ background-color: #eee;
43
+ }
44
+
45
+ .ac_over {
46
+ background-color: #C1E0DB;
47
+ color: white;
48
+ }
js/jquery-autocomplete/jquery.autocomplete.min.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Autocomplete - jQuery plugin 1.0.2
3
+ *
4
+ * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
5
+ *
6
+ * Dual licensed under the MIT and GPL licenses:
7
+ * http://www.opensource.org/licenses/mit-license.php
8
+ * http://www.gnu.org/licenses/gpl.html
9
+ *
10
+ * Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
11
+ *
12
+ */;(function($){$.fn.extend({autocomplete:function(urlOrData,options){var isUrl=typeof urlOrData=="string";options=$.extend({},$.Autocompleter.defaults,{url:isUrl?urlOrData:null,data:isUrl?null:urlOrData,delay:isUrl?$.Autocompleter.defaults.delay:10,max:options&&!options.scroll?10:150},options);options.highlight=options.highlight||function(value){return value;};options.formatMatch=options.formatMatch||options.formatItem;return this.each(function(){new $.Autocompleter(this,options);});},result:function(handler){return this.bind("result",handler);},search:function(handler){return this.trigger("search",[handler]);},flushCache:function(){return this.trigger("flushCache");},setOptions:function(options){return this.trigger("setOptions",[options]);},unautocomplete:function(){return this.trigger("unautocomplete");}});$.Autocompleter=function(input,options){var KEY={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var $input=$(input).attr("autocomplete","off").addClass(options.inputClass);var timeout;var previousValue="";var cache=$.Autocompleter.Cache(options);var hasFocus=0;var lastKeyPressCode;var config={mouseDownOnSelect:false};var select=$.Autocompleter.Select(options,input,selectCurrent,config);var blockSubmit;$.browser.opera&&$(input.form).bind("submit.autocomplete",function(){if(blockSubmit){blockSubmit=false;return false;}});$input.bind(($.browser.opera?"keypress":"keydown")+".autocomplete",function(event){lastKeyPressCode=event.keyCode;switch(event.keyCode){case KEY.UP:event.preventDefault();if(select.visible()){select.prev();}else{onChange(0,true);}break;case KEY.DOWN:event.preventDefault();if(select.visible()){select.next();}else{onChange(0,true);}break;case KEY.PAGEUP:event.preventDefault();if(select.visible()){select.pageUp();}else{onChange(0,true);}break;case KEY.PAGEDOWN:event.preventDefault();if(select.visible()){select.pageDown();}else{onChange(0,true);}break;case options.multiple&&$.trim(options.multipleSeparator)==","&&KEY.COMMA:case KEY.TAB:case KEY.RETURN:if(selectCurrent()){event.preventDefault();blockSubmit=true;return false;}break;case KEY.ESC:select.hide();break;default:clearTimeout(timeout);timeout=setTimeout(onChange,options.delay);break;}}).focus(function(){hasFocus++;}).blur(function(){hasFocus=0;if(!config.mouseDownOnSelect){hideResults();}}).click(function(){if(hasFocus++>1&&!select.visible()){onChange(0,true);}}).bind("search",function(){var fn=(arguments.length>1)?arguments[1]:null;function findValueCallback(q,data){var result;if(data&&data.length){for(var i=0;i<data.length;i++){if(data[i].result.toLowerCase()==q.toLowerCase()){result=data[i];break;}}}if(typeof fn=="function")fn(result);else $input.trigger("result",result&&[result.data,result.value]);}$.each(trimWords($input.val()),function(i,value){request(value,findValueCallback,findValueCallback);});}).bind("flushCache",function(){cache.flush();}).bind("setOptions",function(){$.extend(options,arguments[1]);if("data"in arguments[1])cache.populate();}).bind("unautocomplete",function(){select.unbind();$input.unbind();$(input.form).unbind(".autocomplete");});function selectCurrent(){var selected=select.selected();if(!selected)return false;var v=selected.result;previousValue=v;if(options.multiple){var words=trimWords($input.val());if(words.length>1){v=words.slice(0,words.length-1).join(options.multipleSeparator)+options.multipleSeparator+v;}v+=options.multipleSeparator;}$input.val(v);hideResultsNow();$input.trigger("result",[selected.data,selected.value]);return true;}function onChange(crap,skipPrevCheck){if(lastKeyPressCode==KEY.DEL){select.hide();return;}var currentValue=$input.val();if(!skipPrevCheck&&currentValue==previousValue)return;previousValue=currentValue;currentValue=lastWord(currentValue);if(currentValue.length>=options.minChars){$input.addClass(options.loadingClass);if(!options.matchCase)currentValue=currentValue.toLowerCase();request(currentValue,receiveData,hideResultsNow);}else{stopLoading();select.hide();}};function trimWords(value){if(!value){return[""];}var words=value.split(options.multipleSeparator);var result=[];$.each(words,function(i,value){if($.trim(value))result[i]=$.trim(value);});return result;}function lastWord(value){if(!options.multiple)return value;var words=trimWords(value);return words[words.length-1];}function autoFill(q,sValue){if(options.autoFill&&(lastWord($input.val()).toLowerCase()==q.toLowerCase())&&lastKeyPressCode!=KEY.BACKSPACE){$input.val($input.val()+sValue.substring(lastWord(previousValue).length));$.Autocompleter.Selection(input,previousValue.length,previousValue.length+sValue.length);}};function hideResults(){clearTimeout(timeout);timeout=setTimeout(hideResultsNow,200);};function hideResultsNow(){var wasVisible=select.visible();select.hide();clearTimeout(timeout);stopLoading();if(options.mustMatch){$input.search(function(result){if(!result){if(options.multiple){var words=trimWords($input.val()).slice(0,-1);$input.val(words.join(options.multipleSeparator)+(words.length?options.multipleSeparator:""));}else
13
+ $input.val("");}});}if(wasVisible)$.Autocompleter.Selection(input,input.value.length,input.value.length);};function receiveData(q,data){if(data&&data.length&&hasFocus){stopLoading();select.display(data,q);autoFill(q,data[0].value);select.show();}else{hideResultsNow();}};function request(term,success,failure){if(!options.matchCase)term=term.toLowerCase();var data=cache.load(term);if(data&&data.length){success(term,data);}else if((typeof options.url=="string")&&(options.url.length>0)){var extraParams={timestamp:+new Date()};$.each(options.extraParams,function(key,param){extraParams[key]=typeof param=="function"?param():param;});$.ajax({mode:"abort",port:"autocomplete"+input.name,dataType:options.dataType,url:options.url,data:$.extend({q:lastWord(term),limit:options.max},extraParams),success:function(data){var parsed=options.parse&&options.parse(data)||parse(data);cache.add(term,parsed);success(term,parsed);}});}else{select.emptyList();failure(term);}};function parse(data){var parsed=[];var rows=data.split("\n");for(var i=0;i<rows.length;i++){var row=$.trim(rows[i]);if(row){row=row.split("|");parsed[parsed.length]={data:row,value:row[0],result:options.formatResult&&options.formatResult(row,row[0])||row[0]};}}return parsed;};function stopLoading(){$input.removeClass(options.loadingClass);};};$.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(row){return row[0];},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(value,term){return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>");},scroll:true,scrollHeight:180};$.Autocompleter.Cache=function(options){var data={};var length=0;function matchSubset(s,sub){if(!options.matchCase)s=s.toLowerCase();var i=s.indexOf(sub);if(i==-1)return false;return i==0||options.matchContains;};function add(q,value){if(length>options.cacheLength){flush();}if(!data[q]){length++;}data[q]=value;}function populate(){if(!options.data)return false;var stMatchSets={},nullData=0;if(!options.url)options.cacheLength=1;stMatchSets[""]=[];for(var i=0,ol=options.data.length;i<ol;i++){var rawValue=options.data[i];rawValue=(typeof rawValue=="string")?[rawValue]:rawValue;var value=options.formatMatch(rawValue,i+1,options.data.length);if(value===false)continue;var firstChar=value.charAt(0).toLowerCase();if(!stMatchSets[firstChar])stMatchSets[firstChar]=[];var row={value:value,data:rawValue,result:options.formatResult&&options.formatResult(rawValue)||value};stMatchSets[firstChar].push(row);if(nullData++<options.max){stMatchSets[""].push(row);}};$.each(stMatchSets,function(i,value){options.cacheLength++;add(i,value);});}setTimeout(populate,25);function flush(){data={};length=0;}return{flush:flush,add:add,populate:populate,load:function(q){if(!options.cacheLength||!length)return null;if(!options.url&&options.matchContains){var csub=[];for(var k in data){if(k.length>0){var c=data[k];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub.push(x);}});}}return csub;}else
14
+ if(data[q]){return data[q];}else
15
+ if(options.matchSubset){for(var i=q.length-1;i>=options.minChars;i--){var c=data[q.substr(0,i)];if(c){var csub=[];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub[csub.length]=x;}});return csub;}}}return null;}};};$.Autocompleter.Select=function(options,input,select,config){var CLASSES={ACTIVE:"ac_over"};var listItems,active=-1,data,term="",needsInit=true,element,list;function init(){if(!needsInit)return;element=$("<div/>").hide().addClass(options.resultsClass).css("position","absolute").appendTo(document.body);list=$("<ul/>").appendTo(element).mouseover(function(event){if(target(event).nodeName&&target(event).nodeName.toUpperCase()=='LI'){active=$("li",list).removeClass(CLASSES.ACTIVE).index(target(event));$(target(event)).addClass(CLASSES.ACTIVE);}}).click(function(event){$(target(event)).addClass(CLASSES.ACTIVE);select();input.focus();return false;}).mousedown(function(){config.mouseDownOnSelect=true;}).mouseup(function(){config.mouseDownOnSelect=false;});if(options.width>0)element.css("width",options.width);needsInit=false;}function target(event){var element=event.target;while(element&&element.tagName!="LI")element=element.parentNode;if(!element)return[];return element;}function moveSelect(step){listItems.slice(active,active+1).removeClass(CLASSES.ACTIVE);movePosition(step);var activeItem=listItems.slice(active,active+1).addClass(CLASSES.ACTIVE);if(options.scroll){var offset=0;listItems.slice(0,active).each(function(){offset+=this.offsetHeight;});if((offset+activeItem[0].offsetHeight-list.scrollTop())>list[0].clientHeight){list.scrollTop(offset+activeItem[0].offsetHeight-list.innerHeight());}else if(offset<list.scrollTop()){list.scrollTop(offset);}}};function movePosition(step){active+=step;if(active<0){active=listItems.size()-1;}else if(active>=listItems.size()){active=0;}}function limitNumberOfItems(available){return options.max&&options.max<available?options.max:available;}function fillList(){list.empty();var max=limitNumberOfItems(data.length);for(var i=0;i<max;i++){if(!data[i])continue;var formatted=options.formatItem(data[i].data,i+1,max,data[i].value,term);if(formatted===false)continue;var li=$("<li/>").html(options.highlight(formatted,term)).addClass(i%2==0?"ac_even":"ac_odd").appendTo(list)[0];$.data(li,"ac_data",data[i]);}listItems=list.find("li");if(options.selectFirst){listItems.slice(0,1).addClass(CLASSES.ACTIVE);active=0;}if($.fn.bgiframe)list.bgiframe();}return{display:function(d,q){init();data=d;term=q;fillList();},next:function(){moveSelect(1);},prev:function(){moveSelect(-1);},pageUp:function(){if(active!=0&&active-8<0){moveSelect(-active);}else{moveSelect(-8);}},pageDown:function(){if(active!=listItems.size()-1&&active+8>listItems.size()){moveSelect(listItems.size()-1-active);}else{moveSelect(8);}},hide:function(){element&&element.hide();listItems&&listItems.removeClass(CLASSES.ACTIVE);active=-1;},visible:function(){return element&&element.is(":visible");},current:function(){return this.visible()&&(listItems.filter("."+CLASSES.ACTIVE)[0]||options.selectFirst&&listItems[0]);},show:function(){var offset=$(input).offset();element.css({width:typeof options.width=="string"||options.width>0?options.width:$(input).width(),top:offset.top+input.offsetHeight,left:offset.left}).show();if(options.scroll){list.scrollTop(0);list.css({maxHeight:options.scrollHeight,overflow:'auto'});if($.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var listHeight=0;listItems.each(function(){listHeight+=this.offsetHeight;});var scrollbarsVisible=listHeight>options.scrollHeight;list.css('height',scrollbarsVisible?options.scrollHeight:listHeight);if(!scrollbarsVisible){listItems.width(list.width()-parseInt(listItems.css("padding-left"))-parseInt(listItems.css("padding-right")));}}}},selected:function(){var selected=listItems&&listItems.filter("."+CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);return selected&&selected.length&&$.data(selected[0],"ac_data");},emptyList:function(){list&&list.empty();},unbind:function(){element&&element.remove();}};};$.Autocompleter.Selection=function(field,start,end){if(field.createTextRange){var selRange=field.createTextRange();selRange.collapse(true);selRange.moveStart("character",start);selRange.moveEnd("character",end);selRange.select();}else if(field.setSelectionRange){field.setSelectionRange(start,end);}else{if(field.selectionStart){field.selectionStart=start;field.selectionEnd=end;}}field.focus();};})(jQuery);
js/jquery-autocomplete/jquery.autocomplete.pack.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Autocomplete - jQuery plugin 1.0.2
3
+ *
4
+ * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
5
+ *
6
+ * Dual licensed under the MIT and GPL licenses:
7
+ * http://www.opensource.org/licenses/mit-license.php
8
+ * http://www.gnu.org/licenses/gpl.html
9
+ *
10
+ * Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
11
+ *
12
+ */
13
+ eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}(';(3($){$.31.1o({12:3(b,d){5 c=Y b=="1w";d=$.1o({},$.D.1L,{11:c?b:14,w:c?14:b,1D:c?$.D.1L.1D:10,Z:d&&!d.1x?10:3U},d);d.1t=d.1t||3(a){6 a};d.1q=d.1q||d.1K;6 I.K(3(){1E $.D(I,d)})},M:3(a){6 I.X("M",a)},1y:3(a){6 I.15("1y",[a])},20:3(){6 I.15("20")},1Y:3(a){6 I.15("1Y",[a])},1X:3(){6 I.15("1X")}});$.D=3(o,r){5 t={2N:38,2I:40,2D:46,2x:9,2v:13,2q:27,2d:3x,2j:33,2o:34,2e:8};5 u=$(o).3f("12","3c").P(r.24);5 p;5 m="";5 n=$.D.2W(r);5 s=0;5 k;5 h={1z:B};5 l=$.D.2Q(r,o,1U,h);5 j;$.1T.2L&&$(o.2K).X("3S.12",3(){4(j){j=B;6 B}});u.X(($.1T.2L?"3Q":"3N")+".12",3(a){k=a.2F;3L(a.2F){Q t.2N:a.1d();4(l.L()){l.2y()}A{W(0,C)}N;Q t.2I:a.1d();4(l.L()){l.2u()}A{W(0,C)}N;Q t.2j:a.1d();4(l.L()){l.2t()}A{W(0,C)}N;Q t.2o:a.1d();4(l.L()){l.2s()}A{W(0,C)}N;Q r.19&&$.1p(r.R)==","&&t.2d:Q t.2x:Q t.2v:4(1U()){a.1d();j=C;6 B}N;Q t.2q:l.U();N;3A:1I(p);p=1H(W,r.1D);N}}).1G(3(){s++}).3v(3(){s=0;4(!h.1z){2k()}}).2i(3(){4(s++>1&&!l.L()){W(0,C)}}).X("1y",3(){5 c=(1n.7>1)?1n[1]:14;3 23(q,a){5 b;4(a&&a.7){16(5 i=0;i<a.7;i++){4(a[i].M.O()==q.O()){b=a[i];N}}}4(Y c=="3")c(b);A u.15("M",b&&[b.w,b.H])}$.K(1g(u.J()),3(i,a){1R(a,23,23)})}).X("20",3(){n.18()}).X("1Y",3(){$.1o(r,1n[1]);4("w"2G 1n[1])n.1f()}).X("1X",3(){l.1u();u.1u();$(o.2K).1u(".12")});3 1U(){5 b=l.26();4(!b)6 B;5 v=b.M;m=v;4(r.19){5 a=1g(u.J());4(a.7>1){v=a.17(0,a.7-1).2Z(r.R)+r.R+v}v+=r.R}u.J(v);1l();u.15("M",[b.w,b.H]);6 C}3 W(b,c){4(k==t.2D){l.U();6}5 a=u.J();4(!c&&a==m)6;m=a;a=1k(a);4(a.7>=r.22){u.P(r.21);4(!r.1C)a=a.O();1R(a,2V,1l)}A{1B();l.U()}};3 1g(b){4(!b){6[""]}5 d=b.1Z(r.R);5 c=[];$.K(d,3(i,a){4($.1p(a))c[i]=$.1p(a)});6 c}3 1k(a){4(!r.19)6 a;5 b=1g(a);6 b[b.7-1]}3 1A(q,a){4(r.1A&&(1k(u.J()).O()==q.O())&&k!=t.2e){u.J(u.J()+a.48(1k(m).7));$.D.1N(o,m.7,m.7+a.7)}};3 2k(){1I(p);p=1H(1l,47)};3 1l(){5 c=l.L();l.U();1I(p);1B();4(r.2U){u.1y(3(a){4(!a){4(r.19){5 b=1g(u.J()).17(0,-1);u.J(b.2Z(r.R)+(b.7?r.R:""))}A u.J("")}})}4(c)$.D.1N(o,o.H.7,o.H.7)};3 2V(q,a){4(a&&a.7&&s){1B();l.2T(a,q);1A(q,a[0].H);l.1W()}A{1l()}};3 1R(f,d,g){4(!r.1C)f=f.O();5 e=n.2S(f);4(e&&e.7){d(f,e)}A 4((Y r.11=="1w")&&(r.11.7>0)){5 c={45:+1E 44()};$.K(r.2R,3(a,b){c[a]=Y b=="3"?b():b});$.43({42:"41",3Z:"12"+o.3Y,2M:r.2M,11:r.11,w:$.1o({q:1k(f),3X:r.Z},c),3W:3(a){5 b=r.1r&&r.1r(a)||1r(a);n.1h(f,b);d(f,b)}})}A{l.2J();g(f)}};3 1r(c){5 d=[];5 b=c.1Z("\\n");16(5 i=0;i<b.7;i++){5 a=$.1p(b[i]);4(a){a=a.1Z("|");d[d.7]={w:a,H:a[0],M:r.1v&&r.1v(a,a[0])||a[0]}}}6 d};3 1B(){u.1e(r.21)}};$.D.1L={24:"3R",2H:"3P",21:"3O",22:1,1D:3M,1C:B,1a:C,1V:B,1j:10,Z:3K,2U:B,2R:{},1S:C,1K:3(a){6 a[0]},1q:14,1A:B,E:0,19:B,R:", ",1t:3(b,a){6 b.2C(1E 3J("(?![^&;]+;)(?!<[^<>]*)("+a.2C(/([\\^\\$\\(\\)\\[\\]\\{\\}\\*\\.\\+\\?\\|\\\\])/2A,"\\\\$1")+")(?![^<>]*>)(?![^&;]+;)","2A"),"<2z>$1</2z>")},1x:C,1s:3I};$.D.2W=3(g){5 h={};5 j=0;3 1a(s,a){4(!g.1C)s=s.O();5 i=s.3H(a);4(i==-1)6 B;6 i==0||g.1V};3 1h(q,a){4(j>g.1j){18()}4(!h[q]){j++}h[q]=a}3 1f(){4(!g.w)6 B;5 f={},2w=0;4(!g.11)g.1j=1;f[""]=[];16(5 i=0,30=g.w.7;i<30;i++){5 c=g.w[i];c=(Y c=="1w")?[c]:c;5 d=g.1q(c,i+1,g.w.7);4(d===B)1P;5 e=d.3G(0).O();4(!f[e])f[e]=[];5 b={H:d,w:c,M:g.1v&&g.1v(c)||d};f[e].1O(b);4(2w++<g.Z){f[""].1O(b)}};$.K(f,3(i,a){g.1j++;1h(i,a)})}1H(1f,25);3 18(){h={};j=0}6{18:18,1h:1h,1f:1f,2S:3(q){4(!g.1j||!j)6 14;4(!g.11&&g.1V){5 a=[];16(5 k 2G h){4(k.7>0){5 c=h[k];$.K(c,3(i,x){4(1a(x.H,q)){a.1O(x)}})}}6 a}A 4(h[q]){6 h[q]}A 4(g.1a){16(5 i=q.7-1;i>=g.22;i--){5 c=h[q.3F(0,i)];4(c){5 a=[];$.K(c,3(i,x){4(1a(x.H,q)){a[a.7]=x}});6 a}}}6 14}}};$.D.2Q=3(e,g,f,k){5 h={G:"3E"};5 j,y=-1,w,1m="",1M=C,F,z;3 2r(){4(!1M)6;F=$("<3D/>").U().P(e.2H).T("3C","3B").1J(2p.2n);z=$("<3z/>").1J(F).3y(3(a){4(V(a).2m&&V(a).2m.3w()==\'2l\'){y=$("1F",z).1e(h.G).3u(V(a));$(V(a)).P(h.G)}}).2i(3(a){$(V(a)).P(h.G);f();g.1G();6 B}).3t(3(){k.1z=C}).3s(3(){k.1z=B});4(e.E>0)F.T("E",e.E);1M=B}3 V(a){5 b=a.V;3r(b&&b.3q!="2l")b=b.3p;4(!b)6[];6 b}3 S(b){j.17(y,y+1).1e(h.G);2h(b);5 a=j.17(y,y+1).P(h.G);4(e.1x){5 c=0;j.17(0,y).K(3(){c+=I.1i});4((c+a[0].1i-z.1c())>z[0].3o){z.1c(c+a[0].1i-z.3n())}A 4(c<z.1c()){z.1c(c)}}};3 2h(a){y+=a;4(y<0){y=j.1b()-1}A 4(y>=j.1b()){y=0}}3 2g(a){6 e.Z&&e.Z<a?e.Z:a}3 2f(){z.2B();5 b=2g(w.7);16(5 i=0;i<b;i++){4(!w[i])1P;5 a=e.1K(w[i].w,i+1,b,w[i].H,1m);4(a===B)1P;5 c=$("<1F/>").3m(e.1t(a,1m)).P(i%2==0?"3l":"3k").1J(z)[0];$.w(c,"2c",w[i])}j=z.3j("1F");4(e.1S){j.17(0,1).P(h.G);y=0}4($.31.2b)z.2b()}6{2T:3(d,q){2r();w=d;1m=q;2f()},2u:3(){S(1)},2y:3(){S(-1)},2t:3(){4(y!=0&&y-8<0){S(-y)}A{S(-8)}},2s:3(){4(y!=j.1b()-1&&y+8>j.1b()){S(j.1b()-1-y)}A{S(8)}},U:3(){F&&F.U();j&&j.1e(h.G);y=-1},L:3(){6 F&&F.3i(":L")},3h:3(){6 I.L()&&(j.2a("."+h.G)[0]||e.1S&&j[0])},1W:3(){5 a=$(g).3g();F.T({E:Y e.E=="1w"||e.E>0?e.E:$(g).E(),2E:a.2E+g.1i,1Q:a.1Q}).1W();4(e.1x){z.1c(0);z.T({29:e.1s,3e:\'3d\'});4($.1T.3b&&Y 2p.2n.3T.29==="3a"){5 c=0;j.K(3(){c+=I.1i});5 b=c>e.1s;z.T(\'3V\',b?e.1s:c);4(!b){j.E(z.E()-28(j.T("32-1Q"))-28(j.T("32-39")))}}}},26:3(){5 a=j&&j.2a("."+h.G).1e(h.G);6 a&&a.7&&$.w(a[0],"2c")},2J:3(){z&&z.2B()},1u:3(){F&&F.37()}}};$.D.1N=3(b,a,c){4(b.2O){5 d=b.2O();d.36(C);d.35("2P",a);d.4c("2P",c);d.4b()}A 4(b.2Y){b.2Y(a,c)}A{4(b.2X){b.2X=a;b.4a=c}}b.1G()}})(49);',62,261,'|||function|if|var|return|length|||||||||||||||||||||||||data||active|list|else|false|true|Autocompleter|width|element|ACTIVE|value|this|val|each|visible|result|break|toLowerCase|addClass|case|multipleSeparator|moveSelect|css|hide|target|onChange|bind|typeof|max||url|autocomplete||null|trigger|for|slice|flush|multiple|matchSubset|size|scrollTop|preventDefault|removeClass|populate|trimWords|add|offsetHeight|cacheLength|lastWord|hideResultsNow|term|arguments|extend|trim|formatMatch|parse|scrollHeight|highlight|unbind|formatResult|string|scroll|search|mouseDownOnSelect|autoFill|stopLoading|matchCase|delay|new|li|focus|setTimeout|clearTimeout|appendTo|formatItem|defaults|needsInit|Selection|push|continue|left|request|selectFirst|browser|selectCurrent|matchContains|show|unautocomplete|setOptions|split|flushCache|loadingClass|minChars|findValueCallback|inputClass||selected||parseInt|maxHeight|filter|bgiframe|ac_data|COMMA|BACKSPACE|fillList|limitNumberOfItems|movePosition|click|PAGEUP|hideResults|LI|nodeName|body|PAGEDOWN|document|ESC|init|pageDown|pageUp|next|RETURN|nullData|TAB|prev|strong|gi|empty|replace|DEL|top|keyCode|in|resultsClass|DOWN|emptyList|form|opera|dataType|UP|createTextRange|character|Select|extraParams|load|display|mustMatch|receiveData|Cache|selectionStart|setSelectionRange|join|ol|fn|padding|||moveStart|collapse|remove||right|undefined|msie|off|auto|overflow|attr|offset|current|is|find|ac_odd|ac_even|html|innerHeight|clientHeight|parentNode|tagName|while|mouseup|mousedown|index|blur|toUpperCase|188|mouseover|ul|default|absolute|position|div|ac_over|substr|charAt|indexOf|180|RegExp|100|switch|400|keydown|ac_loading|ac_results|keypress|ac_input|submit|style|150|height|success|limit|name|port||abort|mode|ajax|Date|timestamp||200|substring|jQuery|selectionEnd|select|moveEnd'.split('|'),0,{}))
js/jquery-autocomplete/lib/jquery.ajaxQueue.js ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Ajax Queue Plugin
3
+ *
4
+ * Homepage: http://jquery.com/plugins/project/ajaxqueue
5
+ * Documentation: http://docs.jquery.com/AjaxQueue
6
+ */
7
+
8
+ /**
9
+
10
+ <script>
11
+ $(function(){
12
+ jQuery.ajaxQueue({
13
+ url: "test.php",
14
+ success: function(html){ jQuery("ul").append(html); }
15
+ });
16
+ jQuery.ajaxQueue({
17
+ url: "test.php",
18
+ success: function(html){ jQuery("ul").append(html); }
19
+ });
20
+ jQuery.ajaxSync({
21
+ url: "test.php",
22
+ success: function(html){ jQuery("ul").append("<b>"+html+"</b>"); }
23
+ });
24
+ jQuery.ajaxSync({
25
+ url: "test.php",
26
+ success: function(html){ jQuery("ul").append("<b>"+html+"</b>"); }
27
+ });
28
+ });
29
+ </script>
30
+ <ul style="position: absolute; top: 5px; right: 5px;"></ul>
31
+
32
+ */
33
+ /*
34
+ * Queued Ajax requests.
35
+ * A new Ajax request won't be started until the previous queued
36
+ * request has finished.
37
+ */
38
+
39
+ /*
40
+ * Synced Ajax requests.
41
+ * The Ajax request will happen as soon as you call this method, but
42
+ * the callbacks (success/error/complete) won't fire until all previous
43
+ * synced requests have been completed.
44
+ */
45
+
46
+
47
+ (function($) {
48
+
49
+ var ajax = $.ajax;
50
+
51
+ var pendingRequests = {};
52
+
53
+ var synced = [];
54
+ var syncedData = [];
55
+
56
+ $.ajax = function(settings) {
57
+ // create settings for compatibility with ajaxSetup
58
+ settings = jQuery.extend(settings, jQuery.extend({}, jQuery.ajaxSettings, settings));
59
+
60
+ var port = settings.port;
61
+
62
+ switch(settings.mode) {
63
+ case "abort":
64
+ if ( pendingRequests[port] ) {
65
+ pendingRequests[port].abort();
66
+ }
67
+ return pendingRequests[port] = ajax.apply(this, arguments);
68
+ case "queue":
69
+ var _old = settings.complete;
70
+ settings.complete = function(){
71
+ if ( _old )
72
+ _old.apply( this, arguments );
73
+ jQuery([ajax]).dequeue("ajax" + port );;
74
+ };
75
+
76
+ jQuery([ ajax ]).queue("ajax" + port, function(){
77
+ ajax( settings );
78
+ });
79
+ return;
80
+ case "sync":
81
+ var pos = synced.length;
82
+
83
+ synced[ pos ] = {
84
+ error: settings.error,
85
+ success: settings.success,
86
+ complete: settings.complete,
87
+ done: false
88
+ };
89
+
90
+ syncedData[ pos ] = {
91
+ error: [],
92
+ success: [],
93
+ complete: []
94
+ };
95
+
96
+ settings.error = function(){ syncedData[ pos ].error = arguments; };
97
+ settings.success = function(){ syncedData[ pos ].success = arguments; };
98
+ settings.complete = function(){
99
+ syncedData[ pos ].complete = arguments;
100
+ synced[ pos ].done = true;
101
+
102
+ if ( pos == 0 || !synced[ pos-1 ] )
103
+ for ( var i = pos; i < synced.length && synced[i].done; i++ ) {
104
+ if ( synced[i].error ) synced[i].error.apply( jQuery, syncedData[i].error );
105
+ if ( synced[i].success ) synced[i].success.apply( jQuery, syncedData[i].success );
106
+ if ( synced[i].complete ) synced[i].complete.apply( jQuery, syncedData[i].complete );
107
+
108
+ synced[i] = null;
109
+ syncedData[i] = null;
110
+ }
111
+ };
112
+ }
113
+ return ajax.apply(this, arguments);
114
+ };
115
+
116
+ })(jQuery);
js/jquery-autocomplete/lib/jquery.bgiframe.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
2
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
3
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
4
+ *
5
+ * $LastChangedDate: 2007-07-22 01:45:56 +0200 (Son, 22 Jul 2007) $
6
+ * $Rev: 2447 $
7
+ *
8
+ * Version 2.1.1
9
+ */
10
+ (function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&/6.0/.test(navigator.userAgent)){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+'style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+'"/>';return this.each(function(){if($('> iframe.bgiframe',this).length==0)this.insertBefore(document.createElement(html),this.firstChild);});}return this;};})(jQuery);
js/jquery-autocomplete/todo ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ TODO
2
+
3
+ - test formatItem implementation that returns (clickable) anchors
4
+ - bug: handle del key; eg. type a letter, remove it using del, type same letter again: nothing happens
5
+ - handle up/down keys in textarea (prevent default while select is open?)
6
+ - docs: max:0 works, too, "removing" it(??)
7
+ - fix ac_loading/options.loadingClass
8
+ - support/enable request urls like foo/bar/10 instead of foo/q=10
9
+ - urlencode request term before passing to $.ajax/data; evaluate why $.ajax doesn't handle that itself, if at all; try with umlauts, russian/danish/chinese characeters (see validate)
10
+ - test what happens when an element gets focused programmatically (maybe even before then autcomplete is applied)
11
+ - check if blur on selecting can be removed
12
+ - fix keyhandling to ignore metakeys, eg. shift; especially important for chinese characters that need more then one key
13
+ - enhance mustMatch: provide event/callback when a value gets deleted
14
+ - handle tab key different then enter, eg. don't blur field or prevent default, just let it move on; in any case, no need to blur the field when selecting a value via tab, unlike return
15
+ - prevent redundant requests on
16
+ - superstring returned no result, no need to query again for substring, eg. pete returned nothing, peter won't either
17
+ - previous query mustn't be requested again, eg. pete returns 10 lines, peter nothing, backspace to pete should get the 10 lines from cache (may need TimeToLive setting for cache to invalidate it)
18
+ - incorporate improvements and suggestions by Hector: http://beta.winserver.com/public/test/MultiSuggestTest.wct
19
+ - json support: An optional JSON format, that assumes a certain JSON format as default and just looks for a dataType "json" to be activated; [records], where each record is { id:String, label:String, moreOptionalValues... }
20
+ - accept callback as first argument to let users implement their own dynamic data (no caching) - consider async API
21
+ - allow users to keep their incomplete value when pressing tab, just mimic the default-browser-autocomplete: tab doesn't select any proposed value -> tab closes the select and works normal otherwise
22
+ - small bug in your autocomplete, When setting autoFill:true I would expect formatResult to be called on autofill, it seems not to be the case.
23
+ - add a callback to allow decoding the response
24
+ - allow modification of not-last value in multiple-fields
25
+ @option Number size Limit the number of items to show at once. Default:
26
+ @option Function parse - TEST AND DOCUMENT ME
27
+ - add option to display selectbox on focus
28
+
29
+ $input.bind("show", function() {
30
+ if ( !select.visible() ) {
31
+ onChange(0, true);
32
+ }
33
+ });
34
+
35
+ - reference: http://capxous.com/
36
+ - add "try ..." hints to demo
37
+ - check out demos
38
+ - reference: http://createwebapp.com/demo/
39
+
40
+ - add option to hide selectbox when no match is found - see comment by Ian on plugin page (14. Juli 2007 04:31)
41
+ - add example for reinitializing an autocomplete using unbind()
42
+
43
+ - Add option to pass through additional arguments to $.ajax, like type to use POST instead of GET
44
+
45
+ - I found out that the problem with UTF-8 not being correctly sent can be solved on the server side by applying (PHP) rawurldecode() function, which decodes the Unicode characters sent by GET method and therefore URL-encoded.
46
+ -> add that hint to docs and examples
47
+
48
+ But I am trying this with these three values: “foo bar”, “foo foo”, and “foo far”, and if I enter “b” (or “ba”) nothing matches, if I enter “f” all three do match, and if I enter “fa” the last one matches.
49
+ The problem seems to be that the cache is implemented with a first-character hashtable, so only after matching the first character, the latter ones are searched for.
50
+
51
+ xml example:
52
+ <script type="text/javascript">
53
+ function parseXML(data) {
54
+ var results = [];
55
+ var branches = $(data).find('item');
56
+ $(branches).each(function() {
57
+ var text = $.trim($(this).find('text').text());
58
+ var value = $.trim($(this).find('value').text());
59
+ //console.log(text);
60
+ //console.log(value);
61
+ results[results.length] = {'data': this, 'result': value, 'value': text};
62
+ });
63
+ $(results).each(function() {
64
+ //console.log('value', this.value);
65
+ //console.log('text', this.text);
66
+ });
67
+ //console.log(results);
68
+ return results;
69
+ };
70
+ $(YourOojHere).autocomplete(SERVER_AJAX_URL, {parse: parseXML});
71
+ </script>
72
+ <?xml version="1.0"?>
73
+ <ajaxresponse>
74
+ <item>
75
+ <text>
76
+ <![CDATA[<b>FreeNode:</b> irc.freenode.net:6667]]>
77
+ </text>
78
+ <value><![CDATA[irc.freenode.net:6667]]></value>
79
+ </item><item>
80
+ <text>
81
+ <![CDATA[<b>irc.oftc.net</b>:6667]]>
82
+ </text>
83
+ <value><![CDATA[irc.oftc.net:6667]]></value>
84
+ </item><item>
85
+ <text>
86
+ <![CDATA[<b>irc.undernet.org</b>:6667]]>
87
+ </text>
88
+ <value><![CDATA[irc.undernet.org:6667]]></value>
89
+ </item>
90
+ </ajaxresponse>
91
+
92
+
93
+
94
+ Hi all,
95
+
96
+ I use Autocomplete 1.0 Alpha mostly for form inputs bound to foreign
97
+ key columns. For instance I have a user_position table with two
98
+ columns: user_id and position_id. On new appointment form I have two
99
+ autocomplete text inputs with the following code:
100
+
101
+ <input type="text" id="user_id" class="ac_input" tabindex="1" />
102
+ <input type="text" id="position_id" class="ac_input" tabindex="2" />
103
+
104
+ As you can see the inputs do not have a name attribute, and when the
105
+ form is submitted their values are not sent, which is all right since
106
+ they will contain strings like:
107
+
108
+ 'John Doe'
109
+ 'Sales Manager'
110
+
111
+ whereas our backend expects something like:
112
+
113
+ 23
114
+ 14
115
+
116
+ which are the user_id for John Doe and position_id for Sales Manager.
117
+ To send these values I have two hidden inputs in the form like this:
118
+
119
+ <input type="hidden" name="user_id" value="">
120
+ <input type="hidden" name="position_id" value="">
121
+
122
+ Also I have the following code in the $().ready function:
123
+
124
+ $("#user_id").result(function(event, data, formatted) {
125
+ $("input[@name=user_id]").val(data[1]);
126
+ });
127
+ $("#position_id").result(function(event, data, formatted) {
128
+ $("input[@name=position_id]").val(data[1]);
129
+ });
130
+
131
+ As could be seen these functions stuff user_id and position_id values
132
+ (in our example 23 and 14) into the hidden inputs, and when the form
133
+ is submitted these values are sent:
134
+
135
+ user_id = 23
136
+ position_id = 14
137
+
138
+ The backend script then takes care of adding a record to our
139
+ user_position table containing those values.
140
+
141
+ I wonder how could the plugin code be modified to simplify the setup
142
+ by taking care of adding hidden inputs and updating the value of
143
+ hidden inputs as default behavior. I have successfully attempted a
144
+ simpler solution - writing a wrapper to perform these additional tasks
145
+ and invoke autocomplete as well. I hope my intention is clear enough,
146
+ if not, this is exactly the expected outcome:
147
+
148
+ Before:
149
+
150
+ <script type="text/javascript"
151
+ src="jquery.autocomplete-modified.js"></script>
152
+ <input type="text" name="user_id" class="ac_input" tabindex="1" />
153
+
154
+ After:
155
+
156
+ <input type="text" id="user_id" class="ac_input" tabindex="1" />
157
+ <input type="hidden" name="user_id" value="23">
158
+
159
+
160
+ Last word, I know this looks like a tall order, and I do not hope
161
+ someone will make a complete working mod for me, but rather would very
162
+ much appreciate helpful advise and directions.
163
+
164
+ Many thanks in advance
165
+ Majid
166
+
js/jquery-ui-datepicker/ui.datepicker.css ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Main Style Sheet for jQuery UI date picker */
2
+ #ui-datepicker-div, .ui-datepicker-inline {
3
+ font-family: Arial, Helvetica, sans-serif;
4
+ font-size: 14px;
5
+ padding: 0;
6
+ margin: 0;
7
+ background: #ddd;
8
+ width: 185px;
9
+ }
10
+ #ui-datepicker-div {
11
+ display: none;
12
+ border: 1px solid #777;
13
+ z-index: 100; /*must have*/
14
+ }
15
+ .ui-datepicker-inline {
16
+ float: left;
17
+ display: block;
18
+ border: 0;
19
+ }
20
+ .ui-datepicker-rtl {
21
+ direction: rtl;
22
+ }
23
+ .ui-datepicker-dialog {
24
+ padding: 5px !important;
25
+ border: 4px ridge #ddd !important;
26
+ }
27
+ .ui-datepicker-disabled {
28
+ position: absolute;
29
+ z-index: 100;
30
+ background-color: white;
31
+ opacity: 0.5;
32
+ }
33
+ button.ui-datepicker-trigger {
34
+ width: 25px;
35
+ }
36
+ img.ui-datepicker-trigger {
37
+ margin: 2px;
38
+ vertical-align: middle;
39
+ }
40
+ .ui-datepicker-prompt {
41
+ float: left;
42
+ padding: 2px;
43
+ background: #ddd;
44
+ color: #000;
45
+ }
46
+ * html .ui-datepicker-prompt {
47
+ width: 185px;
48
+ }
49
+ .ui-datepicker-control, .ui-datepicker-links, .ui-datepicker-header, .ui-datepicker {
50
+ clear: both;
51
+ float: left;
52
+ width: 100%;
53
+ color: #fff;
54
+ }
55
+ .ui-datepicker-control {
56
+ background: #400;
57
+ padding: 2px 0px;
58
+ }
59
+ .ui-datepicker-links {
60
+ background: #000;
61
+ padding: 2px 0px;
62
+ }
63
+ .ui-datepicker-control, .ui-datepicker-links {
64
+ font-weight: bold;
65
+ font-size: 80%;
66
+ }
67
+ .ui-datepicker-links label { /* disabled links */
68
+ padding: 2px 5px;
69
+ color: #888;
70
+ }
71
+ .ui-datepicker-clear, .ui-datepicker-prev {
72
+ float: left;
73
+ width: 34%;
74
+ }
75
+ .ui-datepicker-rtl .ui-datepicker-clear, .ui-datepicker-rtl .ui-datepicker-prev {
76
+ float: right;
77
+ text-align: right;
78
+ }
79
+ .ui-datepicker-current {
80
+ float: left;
81
+ width: 30%;
82
+ text-align: center;
83
+ }
84
+ .ui-datepicker-close, .ui-datepicker-next {
85
+ float: right;
86
+ width: 34%;
87
+ text-align: right;
88
+ }
89
+ .ui-datepicker-rtl .ui-datepicker-close, .ui-datepicker-rtl .ui-datepicker-next {
90
+ float: left;
91
+ text-align: left;
92
+ }
93
+ .ui-datepicker-header {
94
+ padding: 1px 0 3px;
95
+ background: #333;
96
+ text-align: center;
97
+ font-weight: bold;
98
+ height: 1.3em;
99
+ }
100
+ .ui-datepicker-header select {
101
+ background: #333;
102
+ color: #fff;
103
+ border: 0px;
104
+ font-weight: bold;
105
+ }
106
+ .ui-datepicker {
107
+ background: #ccc;
108
+ text-align: center;
109
+ font-size: 100%;
110
+ }
111
+ .ui-datepicker a {
112
+ display: block;
113
+ width: 100%;
114
+ }
115
+ .ui-datepicker-title-row {
116
+ background: #777;
117
+ }
118
+ .ui-datepicker-days-row {
119
+ background: #eee;
120
+ color: #666;
121
+ }
122
+ .ui-datepicker-week-col {
123
+ background: #777;
124
+ color: #fff;
125
+ }
126
+ .ui-datepicker-days-cell {
127
+ color: #000;
128
+ border: 1px solid #ddd;
129
+ }
130
+ .ui-datepicker-days-cell a{
131
+ display: block;
132
+ }
133
+ .ui-datepicker-week-end-cell {
134
+ background: #ddd;
135
+ }
136
+ .ui-datepicker-title-row .ui-datepicker-week-end-cell {
137
+ background: #777;
138
+ }
139
+ .ui-datepicker-days-cell-over {
140
+ background: #fff;
141
+ border: 1px solid #777;
142
+ }
143
+ .ui-datepicker-unselectable {
144
+ color: #888;
145
+ }
146
+ .ui-datepicker-today {
147
+ background: #fcc !important;
148
+ }
149
+ .ui-datepicker-current-day {
150
+ background: #999 !important;
151
+ }
152
+ .ui-datepicker-status {
153
+ background: #ddd;
154
+ width: 100%;
155
+ font-size: 80%;
156
+ text-align: center;
157
+ }
158
+
159
+ /* ________ Datepicker Links _______
160
+
161
+ ** Reset link properties and then override them with !important */
162
+ #ui-datepicker-div a, .ui-datepicker-inline a {
163
+ cursor: pointer;
164
+ margin: 0;
165
+ padding: 0;
166
+ background: none;
167
+ color: #000;
168
+ }
169
+ .ui-datepicker-inline .ui-datepicker-links a {
170
+ padding: 0 5px !important;
171
+ }
172
+ .ui-datepicker-control a, .ui-datepicker-links a {
173
+ padding: 2px 5px !important;
174
+ color: #eee !important;
175
+ }
176
+ .ui-datepicker-title-row a {
177
+ color: #eee !important;
178
+ }
179
+ .ui-datepicker-control a:hover {
180
+ background: #fdd !important;
181
+ color: #333 !important;
182
+ }
183
+ .ui-datepicker-links a:hover, .ui-datepicker-title-row a:hover {
184
+ background: #ddd !important;
185
+ color: #333 !important;
186
+ }
187
+
188
+ /* ___________ MULTIPLE MONTHS _________*/
189
+
190
+ .ui-datepicker-multi .ui-datepicker {
191
+ border: 1px solid #777;
192
+ }
193
+ .ui-datepicker-one-month {
194
+ float: left;
195
+ width: 185px;
196
+ }
197
+ .ui-datepicker-new-row {
198
+ clear: left;
199
+ }
200
+
201
+ /* ___________ IE6 IFRAME FIX ________ */
202
+
203
+ .ui-datepicker-cover {
204
+ display: none; /*sorry for IE5*/
205
+ display/**/: block; /*sorry for IE5*/
206
+ position: absolute; /*must have*/
207
+ z-index: -1; /*must have*/
208
+ filter: mask(); /*must have*/
209
+ top: -4px; /*must have*/
210
+ left: -4px; /*must have*/
211
+ width: 200px; /*must have*/
212
+ height: 200px; /*must have*/
213
+ }
js/jquery-ui-datepicker/ui.datepicker.js ADDED
@@ -0,0 +1,1674 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI Datepicker
3
+ *
4
+ * Copyright (c) 2006, 2007, 2008 Marc Grabanski
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI/Datepicker
9
+ *
10
+ * Depends:
11
+ * ui.core.js
12
+ *
13
+ * Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@virginbroadband.com.au).
14
+ */
15
+
16
+ (function($) { // hide the namespace
17
+
18
+ var PROP_NAME = 'datepicker';
19
+
20
+ /* Date picker manager.
21
+ Use the singleton instance of this class, $.datepicker, to interact with the date picker.
22
+ Settings for (groups of) date pickers are maintained in an instance object,
23
+ allowing multiple different settings on the same page. */
24
+
25
+ function Datepicker() {
26
+ this.debug = false; // Change this to true to start debugging
27
+ this._curInst = null; // The current instance in use
28
+ this._disabledInputs = []; // List of date picker inputs that have been disabled
29
+ this._datepickerShowing = false; // True if the popup picker is showing , false if not
30
+ this._inDialog = false; // True if showing within a "dialog", false if not
31
+ this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
32
+ this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
33
+ this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
34
+ this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
35
+ this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
36
+ this._promptClass = 'ui-datepicker-prompt'; // The name of the dialog prompt marker class
37
+ this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
38
+ this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
39
+ this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
40
+ this.regional = []; // Available regional settings, indexed by language code
41
+ this.regional[''] = { // Default regional settings
42
+ clearText: 'Clear', // Display text for clear link
43
+ clearStatus: 'Erase the current date', // Status text for clear link
44
+ closeText: 'Close', // Display text for close link
45
+ closeStatus: 'Close without change', // Status text for close link
46
+ prevText: '&#x3c;Prev', // Display text for previous month link
47
+ prevStatus: 'Show the previous month', // Status text for previous month link
48
+ prevBigText: '&#x3c;&#x3c;', // Display text for previous year link
49
+ prevBigStatus: 'Show the previous year', // Status text for previous year link
50
+ nextText: 'Next&#x3e;', // Display text for next month link
51
+ nextStatus: 'Show the next month', // Status text for next month link
52
+ nextBigText: '&#x3e;&#x3e;', // Display text for next year link
53
+ nextBigStatus: 'Show the next year', // Status text for next year link
54
+ currentText: 'Today', // Display text for current month link
55
+ currentStatus: 'Show the current month', // Status text for current month link
56
+ monthNames: ['January','February','March','April','May','June',
57
+ 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
58
+ monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
59
+ monthStatus: 'Show a different month', // Status text for selecting a month
60
+ yearStatus: 'Show a different year', // Status text for selecting a year
61
+ weekHeader: 'Wk', // Header for the week of the year column
62
+ weekStatus: 'Week of the year', // Status text for the week of the year column
63
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
64
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
65
+ dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
66
+ dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
67
+ dateStatus: 'Select DD, M d', // Status text for the date selection
68
+ dateFormat: 'mm/dd/yy', // See format options on parseDate
69
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
70
+ initStatus: 'Select a date', // Initial Status text on opening
71
+ isRTL: false // True if right-to-left language, false if left-to-right
72
+ };
73
+ this._defaults = { // Global defaults for all the date picker instances
74
+ showOn: 'focus', // 'focus' for popup on focus,
75
+ // 'button' for trigger button, or 'both' for either
76
+ showAnim: 'show', // Name of jQuery animation for popup
77
+ showOptions: {}, // Options for enhanced animations
78
+ defaultDate: null, // Used when field is blank: actual date,
79
+ // +/-number for offset from today, null for today
80
+ appendText: '', // Display text following the input box, e.g. showing the format
81
+ buttonText: '...', // Text for trigger button
82
+ buttonImage: '', // URL for trigger button image
83
+ buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
84
+ closeAtTop: true, // True to have the clear/close at the top,
85
+ // false to have them at the bottom
86
+ mandatory: false, // True to hide the Clear link, false to include it
87
+ hideIfNoPrevNext: false, // True to hide next/previous month links
88
+ // if not applicable, false to just disable them
89
+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
90
+ showBigPrevNext: false, // True to show big prev/next links
91
+ gotoCurrent: false, // True if today link goes back to current selection instead
92
+ changeMonth: true, // True if month can be selected directly, false if only prev/next
93
+ changeYear: true, // True if year can be selected directly, false if only prev/next
94
+ showMonthAfterYear: false, // True if the year select precedes month, false for month then year
95
+ yearRange: '-10:+10', // Range of years to display in drop-down,
96
+ // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
97
+ changeFirstDay: true, // True to click on day name to change, false to remain as set
98
+ highlightWeek: false, // True to highlight the selected week
99
+ showOtherMonths: false, // True to show dates in other months, false to leave blank
100
+ showWeeks: false, // True to show week of the year, false to omit
101
+ calculateWeek: this.iso8601Week, // How to calculate the week of the year,
102
+ // takes a Date and returns the number of the week for it
103
+ shortYearCutoff: '+10', // Short year values < this are in the current century,
104
+ // > this are in the previous century,
105
+ // string value starting with '+' for current year + value
106
+ showStatus: false, // True to show status bar at bottom, false to not show it
107
+ statusForDate: this.dateStatus, // Function to provide status text for a date -
108
+ // takes date and instance as parameters, returns display text
109
+ minDate: null, // The earliest selectable date, or null for no limit
110
+ maxDate: null, // The latest selectable date, or null for no limit
111
+ duration: 'normal', // Duration of display/closure
112
+ beforeShowDay: null, // Function that takes a date and returns an array with
113
+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
114
+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends
115
+ beforeShow: null, // Function that takes an input field and
116
+ // returns a set of custom settings for the date picker
117
+ onSelect: null, // Define a callback function when a date is selected
118
+ onChangeMonthYear: null, // Define a callback function when the month or year is changed
119
+ onClose: null, // Define a callback function when the datepicker is closed
120
+ numberOfMonths: 1, // Number of months to show at a time
121
+ showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
122
+ stepMonths: 1, // Number of months to step back/forward
123
+ stepBigMonths: 12, // Number of months to step back/forward for the big links
124
+ rangeSelect: false, // Allows for selecting a date range on one date picker
125
+ rangeSeparator: ' - ', // Text between two dates in a range
126
+ altField: '', // Selector for an alternate field to store selected dates into
127
+ altFormat: '' // The date format to use for the alternate field
128
+ };
129
+ $.extend(this._defaults, this.regional['']);
130
+ this.dpDiv = $('<div id="' + this._mainDivId + '" style="display: none;"></div>');
131
+ }
132
+
133
+ $.extend(Datepicker.prototype, {
134
+ /* Class name added to elements to indicate already configured with a date picker. */
135
+ markerClassName: 'hasDatepicker',
136
+
137
+ /* Debug logging (if enabled). */
138
+ log: function () {
139
+ if (this.debug)
140
+ console.log.apply('', arguments);
141
+ },
142
+
143
+ /* Override the default settings for all instances of the date picker.
144
+ @param settings object - the new settings to use as defaults (anonymous object)
145
+ @return the manager object */
146
+ setDefaults: function(settings) {
147
+ extendRemove(this._defaults, settings || {});
148
+ return this;
149
+ },
150
+
151
+ /* Attach the date picker to a jQuery selection.
152
+ @param target element - the target input field or division or span
153
+ @param settings object - the new settings to use for this date picker instance (anonymous) */
154
+ _attachDatepicker: function(target, settings) {
155
+ // check for settings on the control itself - in namespace 'date:'
156
+ var inlineSettings = null;
157
+ for (attrName in this._defaults) {
158
+ var attrValue = target.getAttribute('date:' + attrName);
159
+ if (attrValue) {
160
+ inlineSettings = inlineSettings || {};
161
+ try {
162
+ inlineSettings[attrName] = eval(attrValue);
163
+ } catch (err) {
164
+ inlineSettings[attrName] = attrValue;
165
+ }
166
+ }
167
+ }
168
+ var nodeName = target.nodeName.toLowerCase();
169
+ var inline = (nodeName == 'div' || nodeName == 'span');
170
+ if (!target.id)
171
+ target.id = 'dp' + new Date().getTime();
172
+ var inst = this._newInst($(target), inline);
173
+ inst.settings = $.extend({}, settings || {}, inlineSettings || {});
174
+ if (nodeName == 'input') {
175
+ this._connectDatepicker(target, inst);
176
+ } else if (inline) {
177
+ this._inlineDatepicker(target, inst);
178
+ }
179
+ },
180
+
181
+ /* Create a new instance object. */
182
+ _newInst: function(target, inline) {
183
+ var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars
184
+ return {id: id, input: target, // associated target
185
+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
186
+ drawMonth: 0, drawYear: 0, // month being drawn
187
+ inline: inline, // is datepicker inline or not
188
+ dpDiv: (!inline ? this.dpDiv : // presentation div
189
+ $('<div class="' + this._inlineClass + '"></div>'))};
190
+ },
191
+
192
+ /* Attach the date picker to an input field. */
193
+ _connectDatepicker: function(target, inst) {
194
+ var input = $(target);
195
+ if (input.hasClass(this.markerClassName))
196
+ return;
197
+ var appendText = this._get(inst, 'appendText');
198
+ var isRTL = this._get(inst, 'isRTL');
199
+ if (appendText)
200
+ input[isRTL ? 'before' : 'after']('<span class="' + this._appendClass + '">' + appendText + '</span>');
201
+ var showOn = this._get(inst, 'showOn');
202
+ if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
203
+ input.focus(this._showDatepicker);
204
+ if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
205
+ var buttonText = this._get(inst, 'buttonText');
206
+ var buttonImage = this._get(inst, 'buttonImage');
207
+ var trigger = $(this._get(inst, 'buttonImageOnly') ?
208
+ $('<img/>').addClass(this._triggerClass).
209
+ attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
210
+ $('<button type="button"></button>').addClass(this._triggerClass).
211
+ html(buttonImage == '' ? buttonText : $('<img/>').attr(
212
+ { src:buttonImage, alt:buttonText, title:buttonText })));
213
+ input[isRTL ? 'before' : 'after'](trigger);
214
+ trigger.click(function() {
215
+ if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
216
+ $.datepicker._hideDatepicker();
217
+ else
218
+ $.datepicker._showDatepicker(target);
219
+ return false;
220
+ });
221
+ }
222
+ input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).
223
+ bind("setData.datepicker", function(event, key, value) {
224
+ inst.settings[key] = value;
225
+ }).bind("getData.datepicker", function(event, key) {
226
+ return this._get(inst, key);
227
+ });
228
+ $.data(target, PROP_NAME, inst);
229
+ },
230
+
231
+ /* Attach an inline date picker to a div. */
232
+ _inlineDatepicker: function(target, inst) {
233
+ var input = $(target);
234
+ if (input.hasClass(this.markerClassName))
235
+ return;
236
+ input.addClass(this.markerClassName).append(inst.dpDiv).
237
+ bind("setData.datepicker", function(event, key, value){
238
+ inst.settings[key] = value;
239
+ }).bind("getData.datepicker", function(event, key){
240
+ return this._get(inst, key);
241
+ });
242
+ $.data(target, PROP_NAME, inst);
243
+ this._setDate(inst, this._getDefaultDate(inst));
244
+ this._updateDatepicker(inst);
245
+ },
246
+
247
+ /* Tidy up after displaying the date picker. */
248
+ _inlineShow: function(inst) {
249
+ var numMonths = this._getNumberOfMonths(inst); // fix width for dynamic number of date pickers
250
+ inst.dpDiv.width(numMonths[1] * $('.ui-datepicker', inst.dpDiv[0]).width());
251
+ },
252
+
253
+ /* Pop-up the date picker in a "dialog" box.
254
+ @param input element - ignored
255
+ @param dateText string - the initial date to display (in the current format)
256
+ @param onSelect function - the function(dateText) to call when a date is selected
257
+ @param settings object - update the dialog date picker instance's settings (anonymous object)
258
+ @param pos int[2] - coordinates for the dialog's position within the screen or
259
+ event - with x/y coordinates or
260
+ leave empty for default (screen centre)
261
+ @return the manager object */
262
+ _dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
263
+ var inst = this._dialogInst; // internal instance
264
+ if (!inst) {
265
+ var id = 'dp' + new Date().getTime();
266
+ this._dialogInput = $('<input type="text" id="' + id +
267
+ '" size="1" style="position: absolute; top: -100px;"/>');
268
+ this._dialogInput.keydown(this._doKeyDown);
269
+ $('body').append(this._dialogInput);
270
+ inst = this._dialogInst = this._newInst(this._dialogInput, false);
271
+ inst.settings = {};
272
+ $.data(this._dialogInput[0], PROP_NAME, inst);
273
+ }
274
+ extendRemove(inst.settings, settings || {});
275
+ this._dialogInput.val(dateText);
276
+
277
+ this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
278
+ if (!this._pos) {
279
+ var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
280
+ var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
281
+ var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
282
+ var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
283
+ this._pos = // should use actual width/height below
284
+ [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
285
+ }
286
+
287
+ // move input on screen for focus, but hidden behind dialog
288
+ this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
289
+ inst.settings.onSelect = onSelect;
290
+ this._inDialog = true;
291
+ this.dpDiv.addClass(this._dialogClass);
292
+ this._showDatepicker(this._dialogInput[0]);
293
+ if ($.blockUI)
294
+ $.blockUI(this.dpDiv);
295
+ $.data(this._dialogInput[0], PROP_NAME, inst);
296
+ return this;
297
+ },
298
+
299
+ /* Detach a datepicker from its control.
300
+ @param target element - the target input field or division or span */
301
+ _destroyDatepicker: function(target) {
302
+ var $target = $(target);
303
+ if (!$target.hasClass(this.markerClassName)) {
304
+ return;
305
+ }
306
+ var nodeName = target.nodeName.toLowerCase();
307
+ $.removeData(target, PROP_NAME);
308
+ if (nodeName == 'input') {
309
+ $target.siblings('.' + this._appendClass).remove().end().
310
+ siblings('.' + this._triggerClass).remove().end().
311
+ removeClass(this.markerClassName).
312
+ unbind('focus', this._showDatepicker).
313
+ unbind('keydown', this._doKeyDown).
314
+ unbind('keypress', this._doKeyPress);
315
+ } else if (nodeName == 'div' || nodeName == 'span')
316
+ $target.removeClass(this.markerClassName).empty();
317
+ },
318
+
319
+ /* Enable the date picker to a jQuery selection.
320
+ @param target element - the target input field or division or span */
321
+ _enableDatepicker: function(target) {
322
+ var $target = $(target);
323
+ if (!$target.hasClass(this.markerClassName)) {
324
+ return;
325
+ }
326
+ var nodeName = target.nodeName.toLowerCase();
327
+ if (nodeName == 'input') {
328
+ target.disabled = false;
329
+ $target.siblings('button.' + this._triggerClass).
330
+ each(function() { this.disabled = false; }).end().
331
+ siblings('img.' + this._triggerClass).
332
+ css({opacity: '1.0', cursor: ''});
333
+ }
334
+ else if (nodeName == 'div' || nodeName == 'span') {
335
+ $target.children('.' + this._disableClass).remove();
336
+ }
337
+ this._disabledInputs = $.map(this._disabledInputs,
338
+ function(value) { return (value == target ? null : value); }); // delete entry
339
+ },
340
+
341
+ /* Disable the date picker to a jQuery selection.
342
+ @param target element - the target input field or division or span */
343
+ _disableDatepicker: function(target) {
344
+ var $target = $(target);
345
+ if (!$target.hasClass(this.markerClassName)) {
346
+ return;
347
+ }
348
+ var nodeName = target.nodeName.toLowerCase();
349
+ if (nodeName == 'input') {
350
+ target.disabled = true;
351
+ $target.siblings('button.' + this._triggerClass).
352
+ each(function() { this.disabled = true; }).end().
353
+ siblings('img.' + this._triggerClass).
354
+ css({opacity: '0.5', cursor: 'default'});
355
+ }
356
+ else if (nodeName == 'div' || nodeName == 'span') {
357
+ var inline = $target.children('.' + this._inlineClass);
358
+ var offset = inline.offset();
359
+ var relOffset = {left: 0, top: 0};
360
+ inline.parents().each(function() {
361
+ if ($(this).css('position') == 'relative') {
362
+ relOffset = $(this).offset();
363
+ return false;
364
+ }
365
+ });
366
+ $target.prepend('<div class="' + this._disableClass + '" style="' +
367
+ ($.browser.msie ? 'background-color: transparent; ' : '') +
368
+ 'width: ' + inline.width() + 'px; height: ' + inline.height() +
369
+ 'px; left: ' + (offset.left - relOffset.left) +
370
+ 'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>');
371
+ }
372
+ this._disabledInputs = $.map(this._disabledInputs,
373
+ function(value) { return (value == target ? null : value); }); // delete entry
374
+ this._disabledInputs[this._disabledInputs.length] = target;
375
+ },
376
+
377
+ /* Is the first field in a jQuery collection disabled as a datepicker?
378
+ @param target element - the target input field or division or span
379
+ @return boolean - true if disabled, false if enabled */
380
+ _isDisabledDatepicker: function(target) {
381
+ if (!target)
382
+ return false;
383
+ for (var i = 0; i < this._disabledInputs.length; i++) {
384
+ if (this._disabledInputs[i] == target)
385
+ return true;
386
+ }
387
+ return false;
388
+ },
389
+
390
+ /* Update the settings for a date picker attached to an input field or division.
391
+ @param target element - the target input field or division or span
392
+ @param name object - the new settings to update or
393
+ string - the name of the setting to change or
394
+ @param value any - the new value for the setting (omit if above is an object) */
395
+ _changeDatepicker: function(target, name, value) {
396
+ var settings = name || {};
397
+ if (typeof name == 'string') {
398
+ settings = {};
399
+ settings[name] = value;
400
+ }
401
+ var inst = $.data(target, PROP_NAME);
402
+ if (inst) {
403
+ if (this._curInst == inst) {
404
+ this._hideDatepicker(null);
405
+ }
406
+ extendRemove(inst.settings, settings);
407
+ var date = new Date();
408
+ extendRemove(inst, {rangeStart: null, // start of range
409
+ endDay: null, endMonth: null, endYear: null, // end of range
410
+ selectedDay: date.getDate(), selectedMonth: date.getMonth(),
411
+ selectedYear: date.getFullYear(), // starting point
412
+ currentDay: date.getDate(), currentMonth: date.getMonth(),
413
+ currentYear: date.getFullYear(), // current selection
414
+ drawMonth: date.getMonth(), drawYear: date.getFullYear()}); // month being drawn
415
+ this._updateDatepicker(inst);
416
+ }
417
+ },
418
+
419
+ /* Set the dates for a jQuery selection.
420
+ @param target element - the target input field or division or span
421
+ @param date Date - the new date
422
+ @param endDate Date - the new end date for a range (optional) */
423
+ _setDateDatepicker: function(target, date, endDate) {
424
+ var inst = $.data(target, PROP_NAME);
425
+ if (inst) {
426
+ this._setDate(inst, date, endDate);
427
+ this._updateDatepicker(inst);
428
+ }
429
+ },
430
+
431
+ /* Get the date(s) for the first entry in a jQuery selection.
432
+ @param target element - the target input field or division or span
433
+ @return Date - the current date or
434
+ Date[2] - the current dates for a range */
435
+ _getDateDatepicker: function(target) {
436
+ var inst = $.data(target, PROP_NAME);
437
+ if (inst && !inst.inline)
438
+ this._setDateFromField(inst);
439
+ return (inst ? this._getDate(inst) : null);
440
+ },
441
+
442
+ /* Handle keystrokes. */
443
+ _doKeyDown: function(e) {
444
+ var inst = $.data(e.target, PROP_NAME);
445
+ var handled = true;
446
+ if ($.datepicker._datepickerShowing)
447
+ switch (e.keyCode) {
448
+ case 9: $.datepicker._hideDatepicker(null, '');
449
+ break; // hide on tab out
450
+ case 13: $.datepicker._selectDay(e.target, inst.selectedMonth, inst.selectedYear,
451
+ $('td.ui-datepicker-days-cell-over', inst.dpDiv)[0]);
452
+ return false; // don't submit the form
453
+ break; // select the value on enter
454
+ case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
455
+ break; // hide on escape
456
+ case 33: $.datepicker._adjustDate(e.target, (e.ctrlKey ?
457
+ -$.datepicker._get(inst, 'stepBigMonths') :
458
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
459
+ break; // previous month/year on page up/+ ctrl
460
+ case 34: $.datepicker._adjustDate(e.target, (e.ctrlKey ?
461
+ +$.datepicker._get(inst, 'stepBigMonths') :
462
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
463
+ break; // next month/year on page down/+ ctrl
464
+ case 35: if (e.ctrlKey) $.datepicker._clearDate(e.target);
465
+ handled = e.ctrlKey;
466
+ break; // clear on ctrl+end
467
+ case 36: if (e.ctrlKey) $.datepicker._gotoToday(e.target);
468
+ handled = e.ctrlKey;
469
+ break; // current on ctrl+home
470
+ case 37: if (e.ctrlKey) $.datepicker._adjustDate(e.target, -1, 'D');
471
+ handled = e.ctrlKey;
472
+ break; // -1 day on ctrl+left
473
+ case 38: if (e.ctrlKey) $.datepicker._adjustDate(e.target, -7, 'D');
474
+ handled = e.ctrlKey;
475
+ break; // -1 week on ctrl+up
476
+ case 39: if (e.ctrlKey) $.datepicker._adjustDate(e.target, +1, 'D');
477
+ handled = e.ctrlKey;
478
+ break; // +1 day on ctrl+right
479
+ case 40: if (e.ctrlKey) $.datepicker._adjustDate(e.target, +7, 'D');
480
+ handled = e.ctrlKey;
481
+ break; // +1 week on ctrl+down
482
+ default: handled = false;
483
+ }
484
+ else if (e.keyCode == 36 && e.ctrlKey) // display the date picker on ctrl+home
485
+ $.datepicker._showDatepicker(this);
486
+ else
487
+ handled = false;
488
+ if (handled) {
489
+ e.preventDefault();
490
+ e.stopPropagation();
491
+ }
492
+ },
493
+
494
+ /* Filter entered characters - based on date format. */
495
+ _doKeyPress: function(e) {
496
+ var inst = $.data(e.target, PROP_NAME);
497
+ var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
498
+ var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode);
499
+ return e.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
500
+ },
501
+
502
+ /* Pop-up the date picker for a given input field.
503
+ @param input element - the input field attached to the date picker or
504
+ event - if triggered by focus */
505
+ _showDatepicker: function(input) {
506
+ input = input.target || input;
507
+ if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
508
+ input = $('input', input.parentNode)[0];
509
+ if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
510
+ return;
511
+ var inst = $.data(input, PROP_NAME);
512
+ var beforeShow = $.datepicker._get(inst, 'beforeShow');
513
+ extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
514
+ $.datepicker._hideDatepicker(null, '');
515
+ $.datepicker._lastInput = input;
516
+ $.datepicker._setDateFromField(inst);
517
+ if ($.datepicker._inDialog) // hide cursor
518
+ input.value = '';
519
+ if (!$.datepicker._pos) { // position below input
520
+ $.datepicker._pos = $.datepicker._findPos(input);
521
+ $.datepicker._pos[1] += input.offsetHeight; // add the height
522
+ }
523
+ var isFixed = false;
524
+ $(input).parents().each(function() {
525
+ isFixed |= $(this).css('position') == 'fixed';
526
+ return !isFixed;
527
+ });
528
+ if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
529
+ $.datepicker._pos[0] -= document.documentElement.scrollLeft;
530
+ $.datepicker._pos[1] -= document.documentElement.scrollTop;
531
+ }
532
+ var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
533
+ $.datepicker._pos = null;
534
+ inst.rangeStart = null;
535
+ // determine sizing offscreen
536
+ inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
537
+ $.datepicker._updateDatepicker(inst);
538
+ // fix width for dynamic number of date pickers
539
+ inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1] *
540
+ $('.ui-datepicker', inst.dpDiv[0])[0].offsetWidth);
541
+ // and adjust position before showing
542
+ offset = $.datepicker._checkOffset(inst, offset, isFixed);
543
+ inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
544
+ 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
545
+ left: offset.left + 'px', top: offset.top + 'px'});
546
+ if (!inst.inline) {
547
+ var showAnim = $.datepicker._get(inst, 'showAnim') || 'show';
548
+ var duration = $.datepicker._get(inst, 'duration');
549
+ var postProcess = function() {
550
+ $.datepicker._datepickerShowing = true;
551
+ if ($.browser.msie && parseInt($.browser.version) < 7) // fix IE < 7 select problems
552
+ $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,
553
+ height: inst.dpDiv.height() + 4});
554
+ };
555
+ if ($.effects && $.effects[showAnim])
556
+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
557
+ else
558
+ inst.dpDiv[showAnim](duration, postProcess);
559
+ if (duration == '')
560
+ postProcess();
561
+ if (inst.input[0].type != 'hidden')
562
+ inst.input[0].focus();
563
+ $.datepicker._curInst = inst;
564
+ }
565
+ },
566
+
567
+ /* Generate the date picker content. */
568
+ _updateDatepicker: function(inst) {
569
+ var dims = {width: inst.dpDiv.width() + 4,
570
+ height: inst.dpDiv.height() + 4};
571
+ inst.dpDiv.empty().append(this._generateHTML(inst)).
572
+ find('iframe.ui-datepicker-cover').
573
+ css({width: dims.width, height: dims.height});
574
+ var numMonths = this._getNumberOfMonths(inst);
575
+ inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
576
+ 'Class']('ui-datepicker-multi');
577
+ inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
578
+ 'Class']('ui-datepicker-rtl');
579
+ if (inst.input && inst.input[0].type != 'hidden')
580
+ $(inst.input[0]).focus();
581
+ },
582
+
583
+ /* Check positioning to remain on screen. */
584
+ _checkOffset: function(inst, offset, isFixed) {
585
+ var pos = inst.input ? this._findPos(inst.input[0]) : null;
586
+ var browserWidth = window.innerWidth || document.documentElement.clientWidth;
587
+ var browserHeight = window.innerHeight || document.documentElement.clientHeight;
588
+ var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
589
+ var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
590
+ // reposition date picker horizontally if outside the browser window
591
+ if (this._get(inst, 'isRTL') || (offset.left + inst.dpDiv.width() - scrollX) > browserWidth)
592
+ offset.left = Math.max((isFixed ? 0 : scrollX),
593
+ pos[0] + (inst.input ? inst.input.width() : 0) - (isFixed ? scrollX : 0) - inst.dpDiv.width() -
594
+ (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0));
595
+ else
596
+ offset.left -= (isFixed ? scrollX : 0);
597
+ // reposition date picker vertically if outside the browser window
598
+ if ((offset.top + inst.dpDiv.height() - scrollY) > browserHeight)
599
+ offset.top = Math.max((isFixed ? 0 : scrollY),
600
+ pos[1] - (isFixed ? scrollY : 0) - (this._inDialog ? 0 : inst.dpDiv.height()) -
601
+ (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0));
602
+ else
603
+ offset.top -= (isFixed ? scrollY : 0);
604
+ return offset;
605
+ },
606
+
607
+ /* Find an object's position on the screen. */
608
+ _findPos: function(obj) {
609
+ while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
610
+ obj = obj.nextSibling;
611
+ }
612
+ var position = $(obj).offset();
613
+ return [position.left, position.top];
614
+ },
615
+
616
+ /* Hide the date picker from view.
617
+ @param input element - the input field attached to the date picker
618
+ @param duration string - the duration over which to close the date picker */
619
+ _hideDatepicker: function(input, duration) {
620
+ var inst = this._curInst;
621
+ if (!inst || (input && inst != $.data(input, PROP_NAME)))
622
+ return;
623
+ var rangeSelect = this._get(inst, 'rangeSelect');
624
+ if (rangeSelect && inst.stayOpen)
625
+ this._selectDate('#' + inst.id, this._formatDate(inst,
626
+ inst.currentDay, inst.currentMonth, inst.currentYear));
627
+ inst.stayOpen = false;
628
+ if (this._datepickerShowing) {
629
+ duration = (duration != null ? duration : this._get(inst, 'duration'));
630
+ var showAnim = this._get(inst, 'showAnim');
631
+ var postProcess = function() {
632
+ $.datepicker._tidyDialog(inst);
633
+ };
634
+ if (duration != '' && $.effects && $.effects[showAnim])
635
+ inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),
636
+ duration, postProcess);
637
+ else
638
+ inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
639
+ (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
640
+ if (duration == '')
641
+ this._tidyDialog(inst);
642
+ var onClose = this._get(inst, 'onClose');
643
+ if (onClose)
644
+ onClose.apply((inst.input ? inst.input[0] : null),
645
+ [this._getDate(inst), inst]); // trigger custom callback
646
+ this._datepickerShowing = false;
647
+ this._lastInput = null;
648
+ inst.settings.prompt = null;
649
+ if (this._inDialog) {
650
+ this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
651
+ if ($.blockUI) {
652
+ $.unblockUI();
653
+ $('body').append(this.dpDiv);
654
+ }
655
+ }
656
+ this._inDialog = false;
657
+ }
658
+ this._curInst = null;
659
+ },
660
+
661
+ /* Tidy up after a dialog display. */
662
+ _tidyDialog: function(inst) {
663
+ inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker');
664
+ $('.' + this._promptClass, inst.dpDiv).remove();
665
+ },
666
+
667
+ /* Close date picker if clicked elsewhere. */
668
+ _checkExternalClick: function(event) {
669
+ if (!$.datepicker._curInst)
670
+ return;
671
+ var $target = $(event.target);
672
+ if (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&
673
+ !$target.hasClass($.datepicker.markerClassName) &&
674
+ !$target.hasClass($.datepicker._triggerClass) &&
675
+ $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
676
+ $.datepicker._hideDatepicker(null, '');
677
+ },
678
+
679
+ /* Adjust one of the date sub-fields. */
680
+ _adjustDate: function(id, offset, period) {
681
+ var target = $(id);
682
+ var inst = $.data(target[0], PROP_NAME);
683
+ this._adjustInstDate(inst, offset, period);
684
+ this._updateDatepicker(inst);
685
+ },
686
+
687
+ /* Action for current link. */
688
+ _gotoToday: function(id) {
689
+ var target = $(id);
690
+ var inst = $.data(target[0], PROP_NAME);
691
+ if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
692
+ inst.selectedDay = inst.currentDay;
693
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth;
694
+ inst.drawYear = inst.selectedYear = inst.currentYear;
695
+ }
696
+ else {
697
+ var date = new Date();
698
+ inst.selectedDay = date.getDate();
699
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
700
+ inst.drawYear = inst.selectedYear = date.getFullYear();
701
+ }
702
+ this._notifyChange(inst);
703
+ this._adjustDate(target);
704
+ },
705
+
706
+ /* Action for selecting a new month/year. */
707
+ _selectMonthYear: function(id, select, period) {
708
+ var target = $(id);
709
+ var inst = $.data(target[0], PROP_NAME);
710
+ inst._selectingMonthYear = false;
711
+ inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
712
+ inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
713
+ parseInt(select.options[select.selectedIndex].value);
714
+ this._notifyChange(inst);
715
+ this._adjustDate(target);
716
+ },
717
+
718
+ /* Restore input focus after not changing month/year. */
719
+ _clickMonthYear: function(id) {
720
+ var target = $(id);
721
+ var inst = $.data(target[0], PROP_NAME);
722
+ if (inst.input && inst._selectingMonthYear && !$.browser.msie)
723
+ inst.input[0].focus();
724
+ inst._selectingMonthYear = !inst._selectingMonthYear;
725
+ },
726
+
727
+ /* Action for changing the first week day. */
728
+ _changeFirstDay: function(id, day) {
729
+ var target = $(id);
730
+ var inst = $.data(target[0], PROP_NAME);
731
+ inst.settings.firstDay = day;
732
+ this._updateDatepicker(inst);
733
+ },
734
+
735
+ /* Action for selecting a day. */
736
+ _selectDay: function(id, month, year, td) {
737
+ if ($(td).hasClass(this._unselectableClass))
738
+ return;
739
+ var target = $(id);
740
+ var inst = $.data(target[0], PROP_NAME);
741
+ var rangeSelect = this._get(inst, 'rangeSelect');
742
+ if (rangeSelect) {
743
+ inst.stayOpen = !inst.stayOpen;
744
+ if (inst.stayOpen) {
745
+ $('.ui-datepicker td', inst.dpDiv).removeClass(this._currentClass);
746
+ $(td).addClass(this._currentClass);
747
+ }
748
+ }
749
+ inst.selectedDay = inst.currentDay = $('a', td).html();
750
+ inst.selectedMonth = inst.currentMonth = month;
751
+ inst.selectedYear = inst.currentYear = year;
752
+ if (inst.stayOpen) {
753
+ inst.endDay = inst.endMonth = inst.endYear = null;
754
+ }
755
+ else if (rangeSelect) {
756
+ inst.endDay = inst.currentDay;
757
+ inst.endMonth = inst.currentMonth;
758
+ inst.endYear = inst.currentYear;
759
+ }
760
+ this._selectDate(id, this._formatDate(inst,
761
+ inst.currentDay, inst.currentMonth, inst.currentYear));
762
+ if (inst.stayOpen) {
763
+ inst.rangeStart = new Date(inst.currentYear, inst.currentMonth, inst.currentDay);
764
+ this._updateDatepicker(inst);
765
+ }
766
+ else if (rangeSelect) {
767
+ inst.selectedDay = inst.currentDay = inst.rangeStart.getDate();
768
+ inst.selectedMonth = inst.currentMonth = inst.rangeStart.getMonth();
769
+ inst.selectedYear = inst.currentYear = inst.rangeStart.getFullYear();
770
+ inst.rangeStart = null;
771
+ if (inst.inline)
772
+ this._updateDatepicker(inst);
773
+ }
774
+ },
775
+
776
+ /* Erase the input field and hide the date picker. */
777
+ _clearDate: function(id) {
778
+ var target = $(id);
779
+ var inst = $.data(target[0], PROP_NAME);
780
+ if (this._get(inst, 'mandatory'))
781
+ return;
782
+ inst.stayOpen = false;
783
+ inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
784
+ this._selectDate(target, '');
785
+ },
786
+
787
+ /* Update the input field with the selected date. */
788
+ _selectDate: function(id, dateStr) {
789
+ var target = $(id);
790
+ var inst = $.data(target[0], PROP_NAME);
791
+ dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
792
+ if (this._get(inst, 'rangeSelect') && dateStr)
793
+ dateStr = (inst.rangeStart ? this._formatDate(inst, inst.rangeStart) :
794
+ dateStr) + this._get(inst, 'rangeSeparator') + dateStr;
795
+ if (inst.input)
796
+ inst.input.val(dateStr);
797
+ this._updateAlternate(inst);
798
+ var onSelect = this._get(inst, 'onSelect');
799
+ if (onSelect)
800
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
801
+ else if (inst.input)
802
+ inst.input.trigger('change'); // fire the change event
803
+ if (inst.inline)
804
+ this._updateDatepicker(inst);
805
+ else if (!inst.stayOpen) {
806
+ this._hideDatepicker(null, this._get(inst, 'duration'));
807
+ this._lastInput = inst.input[0];
808
+ if (typeof(inst.input[0]) != 'object')
809
+ inst.input[0].focus(); // restore focus
810
+ this._lastInput = null;
811
+ }
812
+ },
813
+
814
+ /* Update any alternate field to synchronise with the main field. */
815
+ _updateAlternate: function(inst) {
816
+ var altField = this._get(inst, 'altField');
817
+ if (altField) { // update alternate field too
818
+ var altFormat = this._get(inst, 'altFormat');
819
+ var date = this._getDate(inst);
820
+ dateStr = (isArray(date) ? (!date[0] && !date[1] ? '' :
821
+ this.formatDate(altFormat, date[0], this._getFormatConfig(inst)) +
822
+ this._get(inst, 'rangeSeparator') + this.formatDate(
823
+ altFormat, date[1] || date[0], this._getFormatConfig(inst))) :
824
+ this.formatDate(altFormat, date, this._getFormatConfig(inst)));
825
+ $(altField).each(function() { $(this).val(dateStr); });
826
+ }
827
+ },
828
+
829
+ /* Set as beforeShowDay function to prevent selection of weekends.
830
+ @param date Date - the date to customise
831
+ @return [boolean, string] - is this date selectable?, what is its CSS class? */
832
+ noWeekends: function(date) {
833
+ var day = date.getDay();
834
+ return [(day > 0 && day < 6), ''];
835
+ },
836
+
837
+ /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
838
+ @param date Date - the date to get the week for
839
+ @return number - the number of the week within the year that contains this date */
840
+ iso8601Week: function(date) {
841
+ var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), (date.getTimezoneOffset() / -60));
842
+ var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
843
+ var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
844
+ firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
845
+ if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
846
+ checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
847
+ return $.datepicker.iso8601Week(checkDate);
848
+ } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
849
+ firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
850
+ if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
851
+ checkDate.setDate(checkDate.getDate() + 3); // Generate for next year
852
+ return $.datepicker.iso8601Week(checkDate);
853
+ }
854
+ }
855
+ return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
856
+ },
857
+
858
+ /* Provide status text for a particular date.
859
+ @param date the date to get the status for
860
+ @param inst the current datepicker instance
861
+ @return the status display text for this date */
862
+ dateStatus: function(date, inst) {
863
+ return $.datepicker.formatDate($.datepicker._get(inst, 'dateStatus'),
864
+ date, $.datepicker._getFormatConfig(inst));
865
+ },
866
+
867
+ /* Parse a string value into a date object.
868
+ See formatDate below for the possible formats.
869
+
870
+ @param format string - the expected format of the date
871
+ @param value string - the date in the above format
872
+ @param settings Object - attributes include:
873
+ shortYearCutoff number - the cutoff year for determining the century (optional)
874
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
875
+ dayNames string[7] - names of the days from Sunday (optional)
876
+ monthNamesShort string[12] - abbreviated names of the months (optional)
877
+ monthNames string[12] - names of the months (optional)
878
+ @return Date - the extracted date value or null if value is blank */
879
+ parseDate: function (format, value, settings) {
880
+ if (format == null || value == null)
881
+ throw 'Invalid arguments';
882
+ value = (typeof value == 'object' ? value.toString() : value + '');
883
+ if (value == '')
884
+ return null;
885
+ var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
886
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
887
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
888
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
889
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
890
+ var year = -1;
891
+ var month = -1;
892
+ var day = -1;
893
+ var doy = -1;
894
+ var literal = false;
895
+ // Check whether a format character is doubled
896
+ var lookAhead = function(match) {
897
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
898
+ if (matches)
899
+ iFormat++;
900
+ return matches;
901
+ };
902
+ // Extract a number from the string value
903
+ var getNumber = function(match) {
904
+ lookAhead(match);
905
+ var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)));
906
+ var size = origSize;
907
+ var num = 0;
908
+ while (size > 0 && iValue < value.length &&
909
+ value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
910
+ num = num * 10 + parseInt(value.charAt(iValue++));
911
+ size--;
912
+ }
913
+ if (size == origSize)
914
+ throw 'Missing number at position ' + iValue;
915
+ return num;
916
+ };
917
+ // Extract a name from the string value and convert to an index
918
+ var getName = function(match, shortNames, longNames) {
919
+ var names = (lookAhead(match) ? longNames : shortNames);
920
+ var size = 0;
921
+ for (var j = 0; j < names.length; j++)
922
+ size = Math.max(size, names[j].length);
923
+ var name = '';
924
+ var iInit = iValue;
925
+ while (size > 0 && iValue < value.length) {
926
+ name += value.charAt(iValue++);
927
+ for (var i = 0; i < names.length; i++)
928
+ if (name == names[i])
929
+ return i + 1;
930
+ size--;
931
+ }
932
+ throw 'Unknown name at position ' + iInit;
933
+ };
934
+ // Confirm that a literal character matches the string value
935
+ var checkLiteral = function() {
936
+ if (value.charAt(iValue) != format.charAt(iFormat))
937
+ throw 'Unexpected literal at position ' + iValue;
938
+ iValue++;
939
+ };
940
+ var iValue = 0;
941
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
942
+ if (literal)
943
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
944
+ literal = false;
945
+ else
946
+ checkLiteral();
947
+ else
948
+ switch (format.charAt(iFormat)) {
949
+ case 'd':
950
+ day = getNumber('d');
951
+ break;
952
+ case 'D':
953
+ getName('D', dayNamesShort, dayNames);
954
+ break;
955
+ case 'o':
956
+ doy = getNumber('o');
957
+ break;
958
+ case 'm':
959
+ month = getNumber('m');
960
+ break;
961
+ case 'M':
962
+ month = getName('M', monthNamesShort, monthNames);
963
+ break;
964
+ case 'y':
965
+ year = getNumber('y');
966
+ break;
967
+ case '@':
968
+ var date = new Date(getNumber('@'));
969
+ year = date.getFullYear();
970
+ month = date.getMonth() + 1;
971
+ day = date.getDate();
972
+ break;
973
+ case "'":
974
+ if (lookAhead("'"))
975
+ checkLiteral();
976
+ else
977
+ literal = true;
978
+ break;
979
+ default:
980
+ checkLiteral();
981
+ }
982
+ }
983
+ if (year < 100)
984
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
985
+ (year <= shortYearCutoff ? 0 : -100);
986
+ if (doy > -1) {
987
+ month = 1;
988
+ day = doy;
989
+ do {
990
+ var dim = this._getDaysInMonth(year, month - 1);
991
+ if (day <= dim)
992
+ break;
993
+ month++;
994
+ day -= dim;
995
+ } while (true);
996
+ }
997
+ var date = new Date(year, month - 1, day);
998
+ if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
999
+ throw 'Invalid date'; // E.g. 31/02/*
1000
+ return date;
1001
+ },
1002
+
1003
+ /* Standard date formats. */
1004
+ ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
1005
+ COOKIE: 'D, dd M yy',
1006
+ ISO_8601: 'yy-mm-dd',
1007
+ RFC_822: 'D, d M y',
1008
+ RFC_850: 'DD, dd-M-y',
1009
+ RFC_1036: 'D, d M y',
1010
+ RFC_1123: 'D, d M yy',
1011
+ RFC_2822: 'D, d M yy',
1012
+ RSS: 'D, d M y', // RFC 822
1013
+ TIMESTAMP: '@',
1014
+ W3C: 'yy-mm-dd', // ISO 8601
1015
+
1016
+ /* Format a date object into a string value.
1017
+ The format can be combinations of the following:
1018
+ d - day of month (no leading zero)
1019
+ dd - day of month (two digit)
1020
+ o - day of year (no leading zeros)
1021
+ oo - day of year (three digit)
1022
+ D - day name short
1023
+ DD - day name long
1024
+ m - month of year (no leading zero)
1025
+ mm - month of year (two digit)
1026
+ M - month name short
1027
+ MM - month name long
1028
+ y - year (two digit)
1029
+ yy - year (four digit)
1030
+ @ - Unix timestamp (ms since 01/01/1970)
1031
+ '...' - literal text
1032
+ '' - single quote
1033
+
1034
+ @param format string - the desired format of the date
1035
+ @param date Date - the date value to format
1036
+ @param settings Object - attributes include:
1037
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
1038
+ dayNames string[7] - names of the days from Sunday (optional)
1039
+ monthNamesShort string[12] - abbreviated names of the months (optional)
1040
+ monthNames string[12] - names of the months (optional)
1041
+ @return string - the date in the above format */
1042
+ formatDate: function (format, date, settings) {
1043
+ if (!date)
1044
+ return '';
1045
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
1046
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
1047
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
1048
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
1049
+ // Check whether a format character is doubled
1050
+ var lookAhead = function(match) {
1051
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
1052
+ if (matches)
1053
+ iFormat++;
1054
+ return matches;
1055
+ };
1056
+ // Format a number, with leading zero if necessary
1057
+ var formatNumber = function(match, value, len) {
1058
+ var num = '' + value;
1059
+ if (lookAhead(match))
1060
+ while (num.length < len)
1061
+ num = '0' + num;
1062
+ return num;
1063
+ };
1064
+ // Format a name, short or long as requested
1065
+ var formatName = function(match, value, shortNames, longNames) {
1066
+ return (lookAhead(match) ? longNames[value] : shortNames[value]);
1067
+ };
1068
+ var output = '';
1069
+ var literal = false;
1070
+ if (date)
1071
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
1072
+ if (literal)
1073
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1074
+ literal = false;
1075
+ else
1076
+ output += format.charAt(iFormat);
1077
+ else
1078
+ switch (format.charAt(iFormat)) {
1079
+ case 'd':
1080
+ output += formatNumber('d', date.getDate(), 2);
1081
+ break;
1082
+ case 'D':
1083
+ output += formatName('D', date.getDay(), dayNamesShort, dayNames);
1084
+ break;
1085
+ case 'o':
1086
+ var doy = date.getDate();
1087
+ for (var m = date.getMonth() - 1; m >= 0; m--)
1088
+ doy += this._getDaysInMonth(date.getFullYear(), m);
1089
+ output += formatNumber('o', doy, 3);
1090
+ break;
1091
+ case 'm':
1092
+ output += formatNumber('m', date.getMonth() + 1, 2);
1093
+ break;
1094
+ case 'M':
1095
+ output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
1096
+ break;
1097
+ case 'y':
1098
+ output += (lookAhead('y') ? date.getFullYear() :
1099
+ (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
1100
+ break;
1101
+ case '@':
1102
+ output += date.getTime();
1103
+ break;
1104
+ case "'":
1105
+ if (lookAhead("'"))
1106
+ output += "'";
1107
+ else
1108
+ literal = true;
1109
+ break;
1110
+ default:
1111
+ output += format.charAt(iFormat);
1112
+ }
1113
+ }
1114
+ return output;
1115
+ },
1116
+
1117
+ /* Extract all possible characters from the date format. */
1118
+ _possibleChars: function (format) {
1119
+ var chars = '';
1120
+ var literal = false;
1121
+ for (var iFormat = 0; iFormat < format.length; iFormat++)
1122
+ if (literal)
1123
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1124
+ literal = false;
1125
+ else
1126
+ chars += format.charAt(iFormat);
1127
+ else
1128
+ switch (format.charAt(iFormat)) {
1129
+ case 'd': case 'm': case 'y': case '@':
1130
+ chars += '0123456789';
1131
+ break;
1132
+ case 'D': case 'M':
1133
+ return null; // Accept anything
1134
+ case "'":
1135
+ if (lookAhead("'"))
1136
+ chars += "'";
1137
+ else
1138
+ literal = true;
1139
+ break;
1140
+ default:
1141
+ chars += format.charAt(iFormat);
1142
+ }
1143
+ return chars;
1144
+ },
1145
+
1146
+ /* Get a setting value, defaulting if necessary. */
1147
+ _get: function(inst, name) {
1148
+ return inst.settings[name] !== undefined ?
1149
+ inst.settings[name] : this._defaults[name];
1150
+ },
1151
+
1152
+ /* Parse existing date and initialise date picker. */
1153
+ _setDateFromField: function(inst) {
1154
+ var dateFormat = this._get(inst, 'dateFormat');
1155
+ var dates = inst.input ? inst.input.val().split(this._get(inst, 'rangeSeparator')) : null;
1156
+ inst.endDay = inst.endMonth = inst.endYear = null;
1157
+ var date = defaultDate = this._getDefaultDate(inst);
1158
+ if (dates.length > 0) {
1159
+ var settings = this._getFormatConfig(inst);
1160
+ if (dates.length > 1) {
1161
+ date = this.parseDate(dateFormat, dates[1], settings) || defaultDate;
1162
+ inst.endDay = date.getDate();
1163
+ inst.endMonth = date.getMonth();
1164
+ inst.endYear = date.getFullYear();
1165
+ }
1166
+ try {
1167
+ date = this.parseDate(dateFormat, dates[0], settings) || defaultDate;
1168
+ } catch (e) {
1169
+ this.log(e);
1170
+ date = defaultDate;
1171
+ }
1172
+ }
1173
+ inst.selectedDay = date.getDate();
1174
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
1175
+ inst.drawYear = inst.selectedYear = date.getFullYear();
1176
+ inst.currentDay = (dates[0] ? date.getDate() : 0);
1177
+ inst.currentMonth = (dates[0] ? date.getMonth() : 0);
1178
+ inst.currentYear = (dates[0] ? date.getFullYear() : 0);
1179
+ this._adjustInstDate(inst);
1180
+ },
1181
+
1182
+ /* Retrieve the default date shown on opening. */
1183
+ _getDefaultDate: function(inst) {
1184
+ var date = this._determineDate(this._get(inst, 'defaultDate'), new Date());
1185
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1186
+ var maxDate = this._getMinMaxDate(inst, 'max');
1187
+ date = (minDate && date < minDate ? minDate : date);
1188
+ date = (maxDate && date > maxDate ? maxDate : date);
1189
+ return date;
1190
+ },
1191
+
1192
+ /* A date may be specified as an exact value or a relative one. */
1193
+ _determineDate: function(date, defaultDate) {
1194
+ var offsetNumeric = function(offset) {
1195
+ var date = new Date();
1196
+ date.setUTCDate(date.getUTCDate() + offset);
1197
+ return date;
1198
+ };
1199
+ var offsetString = function(offset, getDaysInMonth) {
1200
+ var date = new Date();
1201
+ var year = date.getFullYear();
1202
+ var month = date.getMonth();
1203
+ var day = date.getDate();
1204
+ var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
1205
+ var matches = pattern.exec(offset);
1206
+ while (matches) {
1207
+ switch (matches[2] || 'd') {
1208
+ case 'd' : case 'D' :
1209
+ day += parseInt(matches[1]); break;
1210
+ case 'w' : case 'W' :
1211
+ day += parseInt(matches[1]) * 7; break;
1212
+ case 'm' : case 'M' :
1213
+ month += parseInt(matches[1]);
1214
+ day = Math.min(day, getDaysInMonth(year, month));
1215
+ break;
1216
+ case 'y': case 'Y' :
1217
+ year += parseInt(matches[1]);
1218
+ day = Math.min(day, getDaysInMonth(year, month));
1219
+ break;
1220
+ }
1221
+ matches = pattern.exec(offset);
1222
+ }
1223
+ return new Date(year, month, day);
1224
+ };
1225
+ return (date == null ? defaultDate :
1226
+ (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
1227
+ (typeof date == 'number' ? offsetNumeric(date) : date)));
1228
+ },
1229
+
1230
+ /* Set the date(s) directly. */
1231
+ _setDate: function(inst, date, endDate) {
1232
+ var clear = !(date);
1233
+ var origMonth = inst.selectedMonth;
1234
+ var origYear = inst.selectedYear;
1235
+ date = this._determineDate(date, new Date());
1236
+ inst.selectedDay = inst.currentDay = date.getDate();
1237
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
1238
+ inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
1239
+ if (this._get(inst, 'rangeSelect')) {
1240
+ if (endDate) {
1241
+ endDate = this._determineDate(endDate, null);
1242
+ inst.endDay = endDate.getDate();
1243
+ inst.endMonth = endDate.getMonth();
1244
+ inst.endYear = endDate.getFullYear();
1245
+ } else {
1246
+ inst.endDay = inst.currentDay;
1247
+ inst.endMonth = inst.currentMonth;
1248
+ inst.endYear = inst.currentYear;
1249
+ }
1250
+ }
1251
+ if (origMonth != inst.selectedMonth || origYear != inst.selectedYear)
1252
+ this._notifyChange(inst);
1253
+ this._adjustInstDate(inst);
1254
+ if (inst.input)
1255
+ inst.input.val(clear ? '' : this._formatDate(inst) +
1256
+ (!this._get(inst, 'rangeSelect') ? '' : this._get(inst, 'rangeSeparator') +
1257
+ this._formatDate(inst, inst.endDay, inst.endMonth, inst.endYear)));
1258
+ },
1259
+
1260
+ /* Retrieve the date(s) directly. */
1261
+ _getDate: function(inst) {
1262
+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
1263
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
1264
+ if (this._get(inst, 'rangeSelect')) {
1265
+ return [inst.rangeStart || startDate,
1266
+ (!inst.endYear ? inst.rangeStart || startDate :
1267
+ new Date(inst.endYear, inst.endMonth, inst.endDay))];
1268
+ } else
1269
+ return startDate;
1270
+ },
1271
+
1272
+ /* Generate the HTML for the current state of the date picker. */
1273
+ _generateHTML: function(inst) {
1274
+ var today = new Date();
1275
+ today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time
1276
+ var showStatus = this._get(inst, 'showStatus');
1277
+ var initStatus = this._get(inst, 'initStatus') || '&#xa0;';
1278
+ var isRTL = this._get(inst, 'isRTL');
1279
+ // build the date picker HTML
1280
+ var clear = (this._get(inst, 'mandatory') ? '' :
1281
+ '<div class="ui-datepicker-clear"><a onclick="jQuery.datepicker._clearDate(\'#' + inst.id + '\');"' +
1282
+ this._addStatus(showStatus, inst.id, this._get(inst, 'clearStatus'), initStatus) + '>' +
1283
+ this._get(inst, 'clearText') + '</a></div>');
1284
+ var controls = '<div class="ui-datepicker-control">' + (isRTL ? '' : clear) +
1285
+ '<div class="ui-datepicker-close"><a onclick="jQuery.datepicker._hideDatepicker();"' +
1286
+ this._addStatus(showStatus, inst.id, this._get(inst, 'closeStatus'), initStatus) + '>' +
1287
+ this._get(inst, 'closeText') + '</a></div>' + (isRTL ? clear : '') + '</div>';
1288
+ var prompt = this._get(inst, 'prompt');
1289
+ var closeAtTop = this._get(inst, 'closeAtTop');
1290
+ var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
1291
+ var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
1292
+ var showBigPrevNext = this._get(inst, 'showBigPrevNext');
1293
+ var numMonths = this._getNumberOfMonths(inst);
1294
+ var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
1295
+ var stepMonths = this._get(inst, 'stepMonths');
1296
+ var stepBigMonths = this._get(inst, 'stepBigMonths');
1297
+ var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
1298
+ var currentDate = (!inst.currentDay ? new Date(9999, 9, 9) :
1299
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
1300
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1301
+ var maxDate = this._getMinMaxDate(inst, 'max');
1302
+ var drawMonth = inst.drawMonth - showCurrentAtPos;
1303
+ var drawYear = inst.drawYear;
1304
+ if (drawMonth < 0) {
1305
+ drawMonth += 12;
1306
+ drawYear--;
1307
+ }
1308
+ if (maxDate) {
1309
+ var maxDraw = new Date(maxDate.getFullYear(),
1310
+ maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate());
1311
+ maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1312
+ while (new Date(drawYear, drawMonth, 1) > maxDraw) {
1313
+ drawMonth--;
1314
+ if (drawMonth < 0) {
1315
+ drawMonth = 11;
1316
+ drawYear--;
1317
+ }
1318
+ }
1319
+ }
1320
+ // controls and links
1321
+ var prevText = this._get(inst, 'prevText');
1322
+ prevText = (!navigationAsDateFormat ? prevText : this.formatDate(
1323
+ prevText, new Date(drawYear, drawMonth - stepMonths, 1), this._getFormatConfig(inst)));
1324
+ var prevBigText = (showBigPrevNext ? this._get(inst, 'prevBigText') : '');
1325
+ prevBigText = (!navigationAsDateFormat ? prevBigText : this.formatDate(
1326
+ prevBigText, new Date(drawYear, drawMonth - stepBigMonths, 1), this._getFormatConfig(inst)));
1327
+ var prev = '<div class="ui-datepicker-prev">' + (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
1328
+ (showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepBigMonths + ', \'M\');"' +
1329
+ this._addStatus(showStatus, inst.id, this._get(inst, 'prevBigStatus'), initStatus) + '>' + prevBigText + '</a>' : '') +
1330
+ '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
1331
+ this._addStatus(showStatus, inst.id, this._get(inst, 'prevStatus'), initStatus) + '>' + prevText + '</a>' :
1332
+ (hideIfNoPrevNext ? '' : '<label>' + prevBigText + '</label><label>' + prevText + '</label>')) + '</div>';
1333
+ var nextText = this._get(inst, 'nextText');
1334
+ nextText = (!navigationAsDateFormat ? nextText : this.formatDate(
1335
+ nextText, new Date(drawYear, drawMonth + stepMonths, 1), this._getFormatConfig(inst)));
1336
+ var nextBigText = (showBigPrevNext ? this._get(inst, 'nextBigText') : '');
1337
+ nextBigText = (!navigationAsDateFormat ? nextBigText : this.formatDate(
1338
+ nextBigText, new Date(drawYear, drawMonth + stepBigMonths, 1), this._getFormatConfig(inst)));
1339
+ var next = '<div class="ui-datepicker-next">' + (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
1340
+ '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
1341
+ this._addStatus(showStatus, inst.id, this._get(inst, 'nextStatus'), initStatus) + '>' + nextText + '</a>' +
1342
+ (showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepBigMonths + ', \'M\');"' +
1343
+ this._addStatus(showStatus, inst.id, this._get(inst, 'nextBigStatus'), initStatus) + '>' + nextBigText + '</a>' : '') :
1344
+ (hideIfNoPrevNext ? '' : '<label>' + nextText + '</label><label>' + nextBigText + '</label>')) + '</div>';
1345
+ var currentText = this._get(inst, 'currentText');
1346
+ var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
1347
+ currentText = (!navigationAsDateFormat ? currentText :
1348
+ this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
1349
+ var html = (prompt ? '<div class="' + this._promptClass + '">' + prompt + '</div>' : '') +
1350
+ (closeAtTop && !inst.inline ? controls : '') +
1351
+ '<div class="ui-datepicker-links">' + (isRTL ? next : prev) +
1352
+ (this._isInRange(inst, gotoDate) ? '<div class="ui-datepicker-current">' +
1353
+ '<a onclick="jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' +
1354
+ this._addStatus(showStatus, inst.id, this._get(inst, 'currentStatus'), initStatus) + '>' +
1355
+ currentText + '</a></div>' : '') + (isRTL ? prev : next) + '</div>';
1356
+ var firstDay = this._get(inst, 'firstDay');
1357
+ var changeFirstDay = this._get(inst, 'changeFirstDay');
1358
+ var dayNames = this._get(inst, 'dayNames');
1359
+ var dayNamesShort = this._get(inst, 'dayNamesShort');
1360
+ var dayNamesMin = this._get(inst, 'dayNamesMin');
1361
+ var monthNames = this._get(inst, 'monthNames');
1362
+ var beforeShowDay = this._get(inst, 'beforeShowDay');
1363
+ var highlightWeek = this._get(inst, 'highlightWeek');
1364
+ var showOtherMonths = this._get(inst, 'showOtherMonths');
1365
+ var showWeeks = this._get(inst, 'showWeeks');
1366
+ var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
1367
+ var weekStatus = this._get(inst, 'weekStatus');
1368
+ var status = (showStatus ? this._get(inst, 'dayStatus') || initStatus : '');
1369
+ var dateStatus = this._get(inst, 'statusForDate') || this.dateStatus;
1370
+ var endDate = inst.endDay ? new Date(inst.endYear, inst.endMonth, inst.endDay) : currentDate;
1371
+ for (var row = 0; row < numMonths[0]; row++)
1372
+ for (var col = 0; col < numMonths[1]; col++) {
1373
+ var selectedDate = new Date(drawYear, drawMonth, inst.selectedDay);
1374
+ html += '<div class="ui-datepicker-one-month' + (col == 0 ? ' ui-datepicker-new-row' : '') + '">' +
1375
+ this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
1376
+ selectedDate, row > 0 || col > 0, showStatus, initStatus, monthNames) + // draw month headers
1377
+ '<table class="ui-datepicker" cellpadding="0" cellspacing="0"><thead>' +
1378
+ '<tr class="ui-datepicker-title-row">' +
1379
+ (showWeeks ? '<td' + this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' +
1380
+ this._get(inst, 'weekHeader') + '</td>' : '');
1381
+ for (var dow = 0; dow < 7; dow++) { // days of the week
1382
+ var day = (dow + firstDay) % 7;
1383
+ var dayStatus = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) :
1384
+ status.replace(/D/, dayNamesShort[day]));
1385
+ html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end-cell"' : '') + '>' +
1386
+ (!changeFirstDay ? '<span' :
1387
+ '<a onclick="jQuery.datepicker._changeFirstDay(\'#' + inst.id + '\', ' + day + ');"') +
1388
+ this._addStatus(showStatus, inst.id, dayStatus, initStatus) + ' title="' + dayNames[day] + '">' +
1389
+ dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>';
1390
+ }
1391
+ html += '</tr></thead><tbody>';
1392
+ var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1393
+ if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
1394
+ inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
1395
+ var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1396
+ var tzDate = new Date(drawYear, drawMonth, 1 - leadDays);
1397
+ var utcDate = new Date(drawYear, drawMonth, 1 - leadDays);
1398
+ var printDate = utcDate;
1399
+ var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
1400
+ for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
1401
+ html += '<tr class="ui-datepicker-days-row">' +
1402
+ (showWeeks ? '<td class="ui-datepicker-week-col"' +
1403
+ this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' +
1404
+ calculateWeek(printDate) + '</td>' : '');
1405
+ for (var dow = 0; dow < 7; dow++) { // create date picker days
1406
+ var daySettings = (beforeShowDay ?
1407
+ beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
1408
+ var otherMonth = (printDate.getMonth() != drawMonth);
1409
+ var unselectable = otherMonth || !daySettings[0] ||
1410
+ (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1411
+ html += '<td class="ui-datepicker-days-cell' +
1412
+ ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end-cell' : '') + // highlight weekends
1413
+ (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
1414
+ (printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth ?
1415
+ ' ui-datepicker-days-cell-over' : '') + // highlight selected day
1416
+ (unselectable ? ' ' + this._unselectableClass : '') + // highlight unselectable days
1417
+ (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
1418
+ (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
1419
+ ' ' + this._currentClass : '') + // highlight selected day
1420
+ (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
1421
+ ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
1422
+ (unselectable ? (highlightWeek ? ' onmouseover="jQuery(this).parent().addClass(\'ui-datepicker-week-over\');"' + // highlight selection week
1423
+ ' onmouseout="jQuery(this).parent().removeClass(\'ui-datepicker-week-over\');"' : '') : // unhighlight selection week
1424
+ ' onmouseover="jQuery(this).addClass(\'ui-datepicker-days-cell-over\')' + // highlight selection
1425
+ (highlightWeek ? '.parent().addClass(\'ui-datepicker-week-over\')' : '') + ';' + // highlight selection week
1426
+ (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
1427
+ inst.id + '\').html(\'' + (dateStatus.apply((inst.input ? inst.input[0] : null),
1428
+ [printDate, inst]) || initStatus) +'\');') + '"' +
1429
+ ' onmouseout="jQuery(this).removeClass(\'ui-datepicker-days-cell-over\')' + // unhighlight selection
1430
+ (highlightWeek ? '.parent().removeClass(\'ui-datepicker-week-over\')' : '') + ';' + // unhighlight selection week
1431
+ (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
1432
+ inst.id + '\').html(\'' + initStatus + '\');') + '" onclick="jQuery.datepicker._selectDay(\'#' +
1433
+ inst.id + '\',' + drawMonth + ',' + drawYear + ', this);"') + '>' + // actions
1434
+ (otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
1435
+ (unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
1436
+ tzDate.setDate(tzDate.getDate() + 1);
1437
+ utcDate.setUTCDate(utcDate.getUTCDate() + 1);
1438
+ printDate = (tzDate > utcDate ? tzDate : utcDate);
1439
+ }
1440
+ html += '</tr>';
1441
+ }
1442
+ drawMonth++;
1443
+ if (drawMonth > 11) {
1444
+ drawMonth = 0;
1445
+ drawYear++;
1446
+ }
1447
+ html += '</tbody></table></div>';
1448
+ }
1449
+ html += (showStatus ? '<div style="clear: both;"></div><div id="ui-datepicker-status-' + inst.id +
1450
+ '" class="ui-datepicker-status">' + initStatus + '</div>' : '') +
1451
+ (!closeAtTop && !inst.inline ? controls : '') +
1452
+ '<div style="clear: both;"></div>' +
1453
+ ($.browser.msie && parseInt($.browser.version) < 7 && !inst.inline ?
1454
+ '<iframe src="javascript:false;" class="ui-datepicker-cover"></iframe>' : '');
1455
+ return html;
1456
+ },
1457
+
1458
+ /* Generate the month and year header. */
1459
+ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
1460
+ selectedDate, secondary, showStatus, initStatus, monthNames) {
1461
+ minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
1462
+ var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
1463
+ var html = '<div class="ui-datepicker-header">';
1464
+ var monthHtml = '';
1465
+ // month selection
1466
+ if (secondary || !this._get(inst, 'changeMonth'))
1467
+ monthHtml += monthNames[drawMonth] + '&#xa0;';
1468
+ else {
1469
+ var inMinYear = (minDate && minDate.getFullYear() == drawYear);
1470
+ var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
1471
+ monthHtml += '<select class="ui-datepicker-new-month" ' +
1472
+ 'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
1473
+ 'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1474
+ this._addStatus(showStatus, inst.id, this._get(inst, 'monthStatus'), initStatus) + '>';
1475
+ for (var month = 0; month < 12; month++) {
1476
+ if ((!inMinYear || month >= minDate.getMonth()) &&
1477
+ (!inMaxYear || month <= maxDate.getMonth()))
1478
+ monthHtml += '<option value="' + month + '"' +
1479
+ (month == drawMonth ? ' selected="selected"' : '') +
1480
+ '>' + monthNames[month] + '</option>';
1481
+ }
1482
+ monthHtml += '</select>';
1483
+ }
1484
+ if (!showMonthAfterYear)
1485
+ html += monthHtml;
1486
+ // year selection
1487
+ if (secondary || !this._get(inst, 'changeYear'))
1488
+ html += drawYear;
1489
+ else {
1490
+ // determine range of years to display
1491
+ var years = this._get(inst, 'yearRange').split(':');
1492
+ var year = 0;
1493
+ var endYear = 0;
1494
+ if (years.length != 2) {
1495
+ year = drawYear - 10;
1496
+ endYear = drawYear + 10;
1497
+ } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
1498
+ year = endYear = new Date().getFullYear();
1499
+ year += parseInt(years[0], 10);
1500
+ endYear += parseInt(years[1], 10);
1501
+ } else {
1502
+ year = parseInt(years[0], 10);
1503
+ endYear = parseInt(years[1], 10);
1504
+ }
1505
+ year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
1506
+ endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1507
+ html += '<select class="ui-datepicker-new-year" ' +
1508
+ 'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
1509
+ 'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1510
+ this._addStatus(showStatus, inst.id, this._get(inst, 'yearStatus'), initStatus) + '>';
1511
+ for (; year <= endYear; year++) {
1512
+ html += '<option value="' + year + '"' +
1513
+ (year == drawYear ? ' selected="selected"' : '') +
1514
+ '>' + year + '</option>';
1515
+ }
1516
+ html += '</select>';
1517
+ }
1518
+ if (showMonthAfterYear)
1519
+ html += monthHtml;
1520
+ html += '</div>'; // Close datepicker_header
1521
+ return html;
1522
+ },
1523
+
1524
+ /* Provide code to set and clear the status panel. */
1525
+ _addStatus: function(showStatus, id, text, initStatus) {
1526
+ return (showStatus ? ' onmouseover="jQuery(\'#ui-datepicker-status-' + id +
1527
+ '\').html(\'' + (text || initStatus) + '\');" ' +
1528
+ 'onmouseout="jQuery(\'#ui-datepicker-status-' + id +
1529
+ '\').html(\'' + initStatus + '\');"' : '');
1530
+ },
1531
+
1532
+ /* Adjust one of the date sub-fields. */
1533
+ _adjustInstDate: function(inst, offset, period) {
1534
+ var year = inst.drawYear + (period == 'Y' ? offset : 0);
1535
+ var month = inst.drawMonth + (period == 'M' ? offset : 0);
1536
+ var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
1537
+ (period == 'D' ? offset : 0);
1538
+ var date = new Date(year, month, day);
1539
+ // ensure it is within the bounds set
1540
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1541
+ var maxDate = this._getMinMaxDate(inst, 'max');
1542
+ date = (minDate && date < minDate ? minDate : date);
1543
+ date = (maxDate && date > maxDate ? maxDate : date);
1544
+ inst.selectedDay = date.getDate();
1545
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
1546
+ inst.drawYear = inst.selectedYear = date.getFullYear();
1547
+ if (period == 'M' || period == 'Y')
1548
+ this._notifyChange(inst);
1549
+ },
1550
+
1551
+ /* Notify change of month/year. */
1552
+ _notifyChange: function(inst) {
1553
+ var onChange = this._get(inst, 'onChangeMonthYear');
1554
+ if (onChange)
1555
+ onChange.apply((inst.input ? inst.input[0] : null),
1556
+ [new Date(inst.selectedYear, inst.selectedMonth, 1), inst]);
1557
+ },
1558
+
1559
+ /* Determine the number of months to show. */
1560
+ _getNumberOfMonths: function(inst) {
1561
+ var numMonths = this._get(inst, 'numberOfMonths');
1562
+ return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
1563
+ },
1564
+
1565
+ /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
1566
+ _getMinMaxDate: function(inst, minMax, checkRange) {
1567
+ var date = this._determineDate(this._get(inst, minMax + 'Date'), null);
1568
+ if (date) {
1569
+ date.setHours(0);
1570
+ date.setMinutes(0);
1571
+ date.setSeconds(0);
1572
+ date.setMilliseconds(0);
1573
+ }
1574
+ return (!checkRange || !inst.rangeStart ? date :
1575
+ (!date || inst.rangeStart > date ? inst.rangeStart : date));
1576
+ },
1577
+
1578
+ /* Find the number of days in a given month. */
1579
+ _getDaysInMonth: function(year, month) {
1580
+ return 32 - new Date(year, month, 32).getDate();
1581
+ },
1582
+
1583
+ /* Find the day of the week of the first of a month. */
1584
+ _getFirstDayOfMonth: function(year, month) {
1585
+ return new Date(year, month, 1).getDay();
1586
+ },
1587
+
1588
+ /* Determines if we should allow a "next/prev" month display change. */
1589
+ _canAdjustMonth: function(inst, offset, curYear, curMonth) {
1590
+ var numMonths = this._getNumberOfMonths(inst);
1591
+ var date = new Date(curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1);
1592
+ if (offset < 0)
1593
+ date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
1594
+ return this._isInRange(inst, date);
1595
+ },
1596
+
1597
+ /* Is the given date in the accepted range? */
1598
+ _isInRange: function(inst, date) {
1599
+ // during range selection, use minimum of selected date and range start
1600
+ var newMinDate = (!inst.rangeStart ? null :
1601
+ new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay));
1602
+ newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);
1603
+ var minDate = newMinDate || this._getMinMaxDate(inst, 'min');
1604
+ var maxDate = this._getMinMaxDate(inst, 'max');
1605
+ return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
1606
+ },
1607
+
1608
+ /* Provide the configuration settings for formatting/parsing. */
1609
+ _getFormatConfig: function(inst) {
1610
+ var shortYearCutoff = this._get(inst, 'shortYearCutoff');
1611
+ shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
1612
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1613
+ return {shortYearCutoff: shortYearCutoff,
1614
+ dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
1615
+ monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
1616
+ },
1617
+
1618
+ /* Format the given date for display. */
1619
+ _formatDate: function(inst, day, month, year) {
1620
+ if (!day) {
1621
+ inst.currentDay = inst.selectedDay;
1622
+ inst.currentMonth = inst.selectedMonth;
1623
+ inst.currentYear = inst.selectedYear;
1624
+ }
1625
+ var date = (day ? (typeof day == 'object' ? day : new Date(year, month, day)) :
1626
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
1627
+ return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
1628
+ }
1629
+ });
1630
+
1631
+ /* jQuery extend now ignores nulls! */
1632
+ function extendRemove(target, props) {
1633
+ $.extend(target, props);
1634
+ for (var name in props)
1635
+ if (props[name] == null || props[name] == undefined)
1636
+ target[name] = props[name];
1637
+ return target;
1638
+ };
1639
+
1640
+ /* Determine whether an object is an array. */
1641
+ function isArray(a) {
1642
+ return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
1643
+ (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
1644
+ };
1645
+
1646
+ /* Invoke the datepicker functionality.
1647
+ @param options string - a command, optionally followed by additional parameters or
1648
+ Object - settings for attaching new datepicker functionality
1649
+ @return jQuery object */
1650
+ $.fn.datepicker = function(options){
1651
+
1652
+ /* Initialise the date picker. */
1653
+ if (!$.datepicker.initialized) {
1654
+ $(document.body).append($.datepicker.dpDiv).
1655
+ mousedown($.datepicker._checkExternalClick);
1656
+ $.datepicker.initialized = true;
1657
+ }
1658
+
1659
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
1660
+ if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate'))
1661
+ return $.datepicker['_' + options + 'Datepicker'].
1662
+ apply($.datepicker, [this[0]].concat(otherArgs));
1663
+ return this.each(function() {
1664
+ typeof options == 'string' ?
1665
+ $.datepicker['_' + options + 'Datepicker'].
1666
+ apply($.datepicker, [this].concat(otherArgs)) :
1667
+ $.datepicker._attachDatepicker(this, options);
1668
+ });
1669
+ };
1670
+
1671
+ $.datepicker = new Datepicker(); // singleton instance
1672
+ $.datepicker.initialized = false;
1673
+
1674
+ })(jQuery);
js/timeentry/jquery.timeentry-de.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ German initialisation for the jQuery time entry extension
3
+ Written by Eyk Schulz (eyk.schulz@gmx.net) */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['de'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Jetzt', 'vorheriges Feld', 'nächstes Feld', 'hoch', 'runter']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['de']);
9
+ });
js/timeentry/jquery.timeentry-es.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Spanish initialisation for the jQuery time entry extension
3
+ Written by diegok (diego@freekeylabs.com). */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['es'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Ahora', 'Campo anterior', 'Siguiente campo', 'Aumentar', 'Disminuir']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['es']);
9
+ });
js/timeentry/jquery.timeentry-fr.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ French initialisation for the jQuery time entry extension
3
+ Written by Keith Wood (kbwood@iprimus.com.au) June 2007. */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['fr'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Maintenant', 'Précédent', 'Suivant', 'Augmentez', 'Amoindrissez']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['fr']);
9
+ });
js/timeentry/jquery.timeentry-hu.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Hungarian initialisation for the jQuery time entry extension
3
+ Written by Karaszi Istvan (raszi@spam.raszi.hu) */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['hu'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['DE', 'DU'],
7
+ spinnerTexts: ['Most', 'Előző mező', 'Következő mező', 'Növel', 'Csökkent']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['hu']);
9
+ });
js/timeentry/jquery.timeentry-it.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Italian initialisation for the jQuery time entry extension
3
+ Written by Apaella (apaella@gmail.com) June 2007. */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['it'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Adesso', 'Precedente', 'Successivo', 'Aumenta', 'Diminuisci']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['it']);
9
+ });
js/timeentry/jquery.timeentry-nl.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Dutch initialisation written for the jQuery time entry extension.
3
+ Glenn plas (glenn.plas@telenet.be) March 2008. */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['nl'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Nu', 'Vorig veld', 'Volgend veld','Verhoog', 'Verlaag']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['nl']);
9
+ });
js/timeentry/jquery.timeentry-pl.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Polish initialisation for the jQuery time entry extension.
3
+ Polish translation by Jacek Wysocki (jacek.wysocki@gmail.com). */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['pl'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Teraz', 'Poprzednie pole', 'Następne pole', 'Zwiększ wartość', 'Zmniejsz wartość']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['pl']);
9
+ });
js/timeentry/jquery.timeentry-pt.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Portuguese initialisation for the jQuery time entry extension
3
+ Written by Dino Sane (dino@asttra.com.br). */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['pt'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Agora', 'Campo anterior', 'Campo Seguinte', 'Aumentar', 'Diminuir']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['pt']);
9
+ });
js/timeentry/jquery.timeentry-ro.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Romanian initialisation for the jQuery time entry extension
3
+ Written by Edmond L. (ll_edmond@walla.com) */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['ro'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Acum', 'Campul Anterior', 'Campul Urmator', 'Mareste', 'Micsoreaza']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['ro']);
9
+ });
js/timeentry/jquery.timeentry-ru.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Russian (UTF-8) initialisation for the jQuery $.timeEntry extension.
3
+ Written by Andrew Stromnov (stromnov@gmail.com). */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['ru'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Сейчас', 'Предыдущее поле', 'Следующее поле', 'Больше', 'Меньше']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['ru']);
9
+ });
js/timeentry/jquery.timeentry-sk.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Slovak initialisation for the jQuery time entry extension
3
+ Written by Vojtech Rinik (vojto@hmm.sk) */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['sk'] = {show24Hours: false, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Teraz', 'Predchádzajúce pole', 'Nasledujúce pole', 'Zvýšiť', 'Znížiť']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['sk']);
9
+ });
js/timeentry/jquery.timeentry-sv.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Swedish initialisation for the jQuery time entry extension.
3
+ Written by Anders Ekdahl ( anders@nomadiz.se). */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['sv'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['Nu', 'Förra fältet', 'Nästa fält', 'öka', 'minska']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['sv']);
9
+ });
js/timeentry/jquery.timeentry-tr.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Turkish initialisation for the jQuery time entry extension
3
+ Written by Vural Dinçer */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['tr'] = {show24Hours: true, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['şu an', 'önceki alan', 'sonraki alan', 'arttır', 'azalt']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['tr']);
9
+ });
js/timeentry/jquery.timeentry-zh-CN.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Simplified Chinese initialisation for the jQuery time entry extension.
3
+ By Cloudream(cloudream@gmail.com) */
4
+ $(document).ready(function() {
5
+ $.timeEntry.regional['zh-CN'] = {show24Hours: false, separator: ':',
6
+ ampmPrefix: '', ampmNames: ['AM', 'PM'],
7
+ spinnerTexts: ['当前', '左移', '右移', '加一', '减一']};
8
+ $.timeEntry.setDefaults($.timeEntry.regional['zh-CN']);
9
+ });
js/timeentry/jquery.timeentry.compat-1.2.6.js ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Time entry for jQuery compatibility from v1.2.6 to v1.4.0.
3
+ Written by Keith Wood (kbwood@virginbroadband.com.au) June 2007.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+
8
+ (function($) { // Hide scope, no $ conflict
9
+
10
+ $.extend($.timeEntry, {
11
+
12
+ /* Reconfigure the settings for a time entry input field.
13
+ @param input element - input field to update settings for or
14
+ jQuery - jQuery collection containing input field or
15
+ string - jQuery selector for the input field
16
+ @param settings object - the new settings */
17
+ reconfigureFor: function(input, settings) {
18
+ input = (input.jquery ? input[0] : (typeof input == 'string' ? $(input)[0] : input));
19
+ $.timeEntry._changeTimeEntry(input, settings);
20
+ },
21
+
22
+ /* Enable a time entry input and any associated spinner.
23
+ @param inputs string - selector for input field(s) or
24
+ element - single input field or
25
+ object - jQuery collection of input fields
26
+ @return void */
27
+ enableFor: function(inputs) {
28
+ inputs = (inputs.jquery ? inputs : $(inputs));
29
+ inputs.each(function() {
30
+ $.timeEntry._enableTimeEntry(this);
31
+ });
32
+ },
33
+
34
+ /* Disable a time entry input and any associated spinner.
35
+ @param inputs string - selector for input field(s) or
36
+ element - single input field or
37
+ object - jQuery collection of input fields
38
+ @return void */
39
+ disableFor: function(inputs) {
40
+ inputs = (inputs.jquery ? inputs : $(inputs));
41
+ inputs.each(function() {
42
+ $.timeEntry._disableTimeEntry(this);
43
+ });
44
+ },
45
+
46
+ /* Check whether an input field has been disabled.
47
+ @param input element - input field to check or
48
+ jQuery - jQuery collection containing input field or
49
+ string - jQuery selector for the input field
50
+ @return true if this field has been disabled, false if it is enabled */
51
+ isDisabled: function(input) {
52
+ input = (input.jquery ? input[0] : (typeof input == 'string' ? $(input)[0] : input));
53
+ return $.timeEntry._isDisabledTimeEntry(input);
54
+ },
55
+
56
+ /* Initialise the current time for a time entry input field.
57
+ @param input element - input field to update or
58
+ jQuery - jQuery collection containing input field or
59
+ string - jQuery selector for the input field
60
+ @param time Date - the new time (year/month/day ignored) or null for now */
61
+ setTimeFor: function(input, time) {
62
+ input = (input.jquery ? input[0] : (typeof input == 'string' ? $(input)[0] : input));
63
+ $.timeEntry._setTimeTimeEntry(input, time);
64
+ },
65
+
66
+ /* Retrieve the current time for a time entry input field.
67
+ @param input element - input field to update or
68
+ jQuery - jQuery collection containing input field or
69
+ string - jQuery selector for the input field
70
+ @return Date with the set time (year/month/day zero) or null if none */
71
+ getTimeFor: function(input) {
72
+ input = (input.jquery ? input[0] : (typeof input == 'string' ? $(input)[0] : input));
73
+ return $.timeEntry._getTimeTimeEntry(input);
74
+ }
75
+ });
76
+
77
+ })(jQuery);
js/timeentry/jquery.timeentry.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ /* timeEntry styles */
2
+ .timeEntry_control {
3
+ vertical-align: middle;
4
+ margin-left: 2px;
5
+ }
6
+ * html .timeEntry_control { /* IE only */
7
+ margin-top: -4px;
8
+ }
js/timeentry/jquery.timeentry.ent ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!ATTLIST input
2
+ time:ampmNames CDATA #IMPLIED
3
+ time:ampmPrefix CDATA #IMPLIED
4
+ time:appendText CDATA #IMPLIED
5
+ time:beforeSetTime CDATA #IMPLIED
6
+ time:beforeShow CDATA #IMPLIED
7
+ time:defaultTime CDATA #IMPLIED
8
+ time:fieldSettings CDATA #IMPLIED
9
+ time:initialField CDATA #IMPLIED
10
+ time:maxTime CDATA #IMPLIED
11
+ time:minTime CDATA #IMPLIED
12
+ time:separator CDATA #IMPLIED
13
+ time:show24Hours (true | false) #IMPLIED
14
+ time:showSeconds (true | false) #IMPLIED
15
+ time:spinnerImage CDATA #IMPLIED
16
+ time:spinnerIncDecOnly (true | false) #IMPLIED
17
+ time:spinnerRepeat CDATA #IMPLIED
18
+ time:spinnerSize CDATA #IMPLIED
19
+ time:spinnerTexts CDATA #IMPLIED
20
+ time:timeSteps CDATA #IMPLIED
21
+ time:useMouseWheel (true | false) #IMPLIED
22
+ >
js/timeentry/jquery.timeentry.js ADDED
@@ -0,0 +1,900 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Time entry for jQuery v1.4.2.
3
+ Written by Keith Wood (kbwood@virginbroadband.com.au) June 2007.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+
8
+ /* Turn an input field into an entry point for a time value.
9
+ The time can be entered via directly typing the value,
10
+ via the arrow keys, or via spinner buttons.
11
+ It is configurable to show 12 or 24-hour time, to show or hide seconds,
12
+ to enforce a minimum and/or maximum time, to change the spinner image,
13
+ and to constrain the time to steps, e.g. only on the quarter hours.
14
+ Attach it with $('input selector').timeEntry(); for default settings,
15
+ or configure it with options like:
16
+ $('input selector').timeEntry(
17
+ {spinnerImage: 'timeEntry2.png', spinnerSize: [20, 20, 0]}); */
18
+
19
+ (function($) { // Hide scope, no $ conflict
20
+
21
+ /* TimeEntry manager.
22
+ Use the singleton instance of this class, $.timeEntry, to interact with the time entry
23
+ functionality. Settings for (groups of) fields are maintained in an instance object
24
+ (TimeEntryInstance), allowing multiple different settings on the same page. */
25
+ function TimeEntry() {
26
+ this._disabledInputs = []; // List of time entry inputs that have been disabled
27
+ this.regional = []; // Available regional settings, indexed by language code
28
+ this.regional[''] = { // Default regional settings
29
+ show24Hours: false, // True to use 24 hour time, false for 12 hour (AM/PM)
30
+ separator: ':', // The separator between time fields
31
+ ampmPrefix: '', // The separator before the AM/PM text
32
+ ampmNames: ['AM', 'PM'], // Names of morning/evening markers
33
+ spinnerTexts: ['Now', 'Previous field', 'Next field', 'Increment', 'Decrement']
34
+ // The popup texts for the spinner image areas
35
+ };
36
+ this._defaults = {
37
+ appendText: '', // Display text following the input box, e.g. showing the format
38
+ showSeconds: false, // True to show seconds as well, false for hours/minutes only
39
+ timeSteps: [1, 1, 1], // Steps for each of hours/minutes/seconds when incrementing/decrementing
40
+ initialField: 0, // The field to highlight initially, 0 = hours, 1 = minutes, ...
41
+ useMouseWheel: true, // True to use mouse wheel for increment/decrement if possible,
42
+ // false to never use it
43
+ defaultTime: null, // The time to use if none has been set, leave at null for now
44
+ minTime: null, // The earliest selectable time, or null for no limit
45
+ maxTime: null, // The latest selectable time, or null for no limit
46
+ spinnerImage: 'timeEntry.png', // The URL of the images to use for the time spinner
47
+ // Six images packed horizontally for normal and then each button pressed
48
+ spinnerSize: [20, 20, 8], // The width and height of the spinner image,
49
+ // and size of centre button for current time
50
+ spinnerIncDecOnly: false, // True for increment/decrement buttons only, false for all
51
+ spinnerRepeat: [500, 250], // Initial and subsequent waits in milliseconds
52
+ // for repeats on the spinner buttons
53
+ beforeShow: null, // Function that takes an input field and
54
+ // returns a set of custom settings for the time entry
55
+ beforeSetTime: null // Function that runs before updating the time,
56
+ // takes the old and new times, and minimum and maximum times as parameters,
57
+ // and returns an adjusted time if necessary
58
+ };
59
+ $.extend(this._defaults, this.regional['']);
60
+ }
61
+
62
+ var PROP_NAME = 'timeEntry';
63
+
64
+ $.extend(TimeEntry.prototype, {
65
+ /* Class name added to elements to indicate already configured with time entry. */
66
+ markerClassName: 'hasTimeEntry',
67
+
68
+ /* Override the default settings for all instances of the time entry.
69
+ @param options (object) the new settings to use as defaults (anonymous object) */
70
+ setDefaults: function(options) {
71
+ extendRemove(this._defaults, options || {});
72
+ },
73
+
74
+ /* Attach the time entry handler to an input field.
75
+ @param target (element) the field to attach to
76
+ @param options (object) custom settings for this instance */
77
+ _connectTimeEntry: function(target, options) {
78
+ var input = $(target);
79
+ if (input.hasClass(this.markerClassName)) {
80
+ return;
81
+ }
82
+ var inst = {};
83
+ inst.options = $.extend({}, options);
84
+ inst._selectedHour = 0; // The currently selected hour
85
+ inst._selectedMinute = 0; // The currently selected minute
86
+ inst._selectedSecond = 0; // The currently selected second
87
+ inst._field = 0; // The selected subfield
88
+ inst.input = $(target); // The attached input field
89
+ $.data(target, PROP_NAME, inst);
90
+ var spinnerImage = this._get(inst, 'spinnerImage');
91
+ var spinnerText = this._get(inst, 'spinnerText');
92
+ var spinnerSize = this._get(inst, 'spinnerSize');
93
+ var appendText = this._get(inst, 'appendText');
94
+ var spinner = (!spinnerImage ? null :
95
+ $('<span class="timeEntry_control" style="display: inline-block; ' +
96
+ 'background: url(\'' + spinnerImage + '\') 0 0 no-repeat; ' +
97
+ 'width: ' + spinnerSize[0] + 'px; height: ' + spinnerSize[1] + 'px;' +
98
+ ($.browser.mozilla && $.browser.version < '1.9' ? // FF 2- (Win)
99
+ ' padding-left: ' + spinnerSize[0] + 'px; padding-bottom: ' +
100
+ (spinnerSize[1] - 18) + 'px;' : '') + '"></span>'));
101
+ input.wrap('<span class="timeEntry_wrap"></span>').
102
+ after(appendText ? '<span class="timeEntry_append">' + appendText + '</span>' : '').
103
+ after(spinner || '');
104
+ input.addClass(this.markerClassName).bind('focus.timeEntry', this._doFocus).
105
+ bind('blur.timeEntry', this._doBlur).bind('click.timeEntry', this._doClick).
106
+ bind('keydown.timeEntry', this._doKeyDown).bind('keypress.timeEntry', this._doKeyPress);
107
+ // check pastes
108
+ if ($.browser.mozilla) {
109
+ input.bind('input.timeEntry', function(event) { $.timeentry._parseTime(inst); });
110
+ }
111
+ if ($.browser.msie) {
112
+ input.bind('paste.timeEntry',
113
+ function(event) { setTimeout(function() { $.timeentry._parseTime(inst); }, 1); });
114
+ }
115
+ // allow mouse wheel usage
116
+ if (this._get(inst, 'useMouseWheel') && $.fn.mousewheel) {
117
+ input.mousewheel(this._doMouseWheel);
118
+ }
119
+ if (spinner) {
120
+ spinner.mousedown(this._handleSpinner).mouseup(this._endSpinner).
121
+ mouseout(this._endSpinner).mousemove(this._describeSpinner);
122
+ }
123
+ },
124
+
125
+ /* Enable a time entry input and any associated spinner.
126
+ @param input (element) single input field */
127
+ _enableTimeEntry: function(input) {
128
+ this._enableDisable(input, false);
129
+ },
130
+
131
+ /* Disable a time entry input and any associated spinner.
132
+ @param input (element) single input field */
133
+ _disableTimeEntry: function(input) {
134
+ this._enableDisable(input, true);
135
+ },
136
+
137
+ /* Enable or disable a time entry input and any associated spinner.
138
+ @param input (element) single input field
139
+ @param disable (boolean) true to disable, false to enable */
140
+ _enableDisable: function(input, disable) {
141
+ var inst = $.data(input, PROP_NAME);
142
+ if (!inst) {
143
+ return;
144
+ }
145
+ input.disabled = disable;
146
+ if (input.nextSibling && input.nextSibling.nodeName.toLowerCase() == 'span') {
147
+ $.timeEntry._changeSpinner(inst, input.nextSibling, (disable ? 5 : -1));
148
+ }
149
+ $.timeEntry._disabledInputs = $.map($.timeEntry._disabledInputs,
150
+ function(value) { return (value == input ? null : value); }); // delete entry
151
+ if (disable) {
152
+ $.timeEntry._disabledInputs.push(input);
153
+ }
154
+ },
155
+
156
+ /* Check whether an input field has been disabled.
157
+ @param input (element) input field to check
158
+ @return (boolean) true if this field has been disabled, false if it is enabled */
159
+ _isDisabledTimeEntry: function(input) {
160
+ return $.inArray(input, this._disabledInputs) > -1;
161
+ },
162
+
163
+ /* Reconfigure the settings for a time entry field.
164
+ @param input (element) input field to change
165
+ @param options (object) new settings to add */
166
+ _changeTimeEntry: function(input, options) {
167
+ var inst = $.data(input, PROP_NAME);
168
+ if (inst) {
169
+ var currentTime = this._extractTime(inst);
170
+ extendRemove(inst.options, options || {});
171
+ if (currentTime) {
172
+ this._setTime(inst, new Date(0, 0, 0,
173
+ currentTime[0], currentTime[1], currentTime[2]));
174
+ }
175
+ }
176
+ $.data(input, PROP_NAME, inst);
177
+ },
178
+
179
+ /* Remove the time entry functionality from an input.
180
+ @param input (element) input field to affect */
181
+ _destroyTimeEntry: function(input) {
182
+ $input = $(input);
183
+ if (!$input.hasClass(this.markerClassName)) {
184
+ return;
185
+ }
186
+ $input.removeClass(this.markerClassName).unbind('focus.timeEntry').
187
+ unbind('blur.timeEntry').unbind('click.timeEntry').
188
+ unbind('keydown.timeEntry').unbind('keypress.timeEntry');
189
+ // check pastes
190
+ if ($.browser.mozilla) {
191
+ $input.unbind('input.timeEntry');
192
+ }
193
+ if ($.browser.msie) {
194
+ $input.unbind('paste.timeEntry');
195
+ }
196
+ if ($.fn.mousewheel) {
197
+ $input.unmousewheel();
198
+ }
199
+ this._disabledInputs = $.map(this._disabledInputs,
200
+ function(value) { return (value == input ? null : value); }); // delete entry
201
+ $input.parent().replaceWith($input);
202
+ $.removeData(input, PROP_NAME);
203
+ },
204
+
205
+ /* Initialise the current time for a time entry input field.
206
+ @param input (element) input field to update
207
+ @param time (Date) the new time (year/month/day ignored) or null for now */
208
+ _setTimeTimeEntry: function(input, time) {
209
+ var inst = $.data(input, PROP_NAME);
210
+ if (inst) {
211
+ this._setTime(inst, time ? (typeof time == 'object' ?
212
+ new Date(time.getTime()) : time) : null);
213
+ }
214
+ },
215
+
216
+ /* Retrieve the current time for a time entry input field.
217
+ @param input (element) input field to update
218
+ @return (Date) current time (year/month/day zero) or null if none */
219
+ _getTimeTimeEntry: function(input) {
220
+ var inst = $.data(input, PROP_NAME);
221
+ var currentTime = (inst ? this._extractTime(inst) : null);
222
+ return (!currentTime ? null :
223
+ new Date(0, 0, 0, currentTime[0], currentTime[1], currentTime[2]));
224
+ },
225
+
226
+ /* Initialise time entry.
227
+ @param target (element) the input field or
228
+ (event) the focus event */
229
+ _doFocus: function(target) {
230
+ var input = (target.nodeName && target.nodeName.toLowerCase() == 'input' ? target : this);
231
+ if ($.timeEntry._lastInput == input) { // already here
232
+ return;
233
+ }
234
+ if ($.timeEntry._isDisabledTimeEntry(input)) {
235
+ return;
236
+ }
237
+ var inst = $.data(input, PROP_NAME);
238
+ $.timeEntry._focussed = true;
239
+ $.timeEntry._lastInput = input;
240
+ $.timeEntry._blurredInput = null;
241
+ var beforeShow = $.timeEntry._get(inst, 'beforeShow');
242
+ extendRemove(inst.options, (beforeShow ? beforeShow.apply(input, [input]) : {}));
243
+ $.data(input, PROP_NAME, inst);
244
+ $.timeEntry._parseTime(inst);
245
+ },
246
+
247
+ /* Note that the field has been exited.
248
+ @param event (event) the blur event */
249
+ _doBlur: function(event) {
250
+ $.timeEntry._blurredInput = $.timeEntry._lastInput;
251
+ $.timeEntry._lastInput = null;
252
+ },
253
+
254
+ /* Select appropriate field portion on click, if already in the field.
255
+ @param event (event) the click event */
256
+ _doClick: function(event) {
257
+ var input = event.target;
258
+ var inst = $.data(input, PROP_NAME);
259
+ if (!$.timeEntry._focussed) {
260
+ var fieldSize = $.timeEntry._get(inst, 'separator').length + 2;
261
+ inst._field = 0;
262
+ if ($.browser.msie) { // check against bounding boxes
263
+ var value = input.value;
264
+ var offsetX = event.clientX + document.documentElement.scrollLeft -
265
+ $(event.srcElement).offset().left;
266
+ for (var field = 0; field <= Math.max(1, inst._secondField, inst._ampmField); field++) {
267
+ var end = (field != inst._ampmField ? (field * fieldSize) + 2 :
268
+ (inst._ampmField * fieldSize) + $.timeEntry._get(inst, 'ampmPrefix').length +
269
+ $.timeEntry._get(inst, 'ampmNames')[0].length);
270
+ input.value = value.substring(0, end); // trim to this size
271
+ var range = input.createTextRange();
272
+ if (offsetX < range.boundingWidth) { // and compare
273
+ inst._field = field;
274
+ break;
275
+ }
276
+ }
277
+ input.value = value; // restore original value
278
+ }
279
+ else { // use input select range
280
+ for (var field = 0; field <= Math.max(1, inst._secondField, inst._ampmField); field++) {
281
+ var start = (field != inst._ampmField ? (field * fieldSize) + 2 :
282
+ (inst._ampmField * fieldSize) + $.timeEntry._get(inst, 'ampmPrefix').length +
283
+ $.timeEntry._get(inst, 'ampmNames')[0].length);
284
+ if (input.selectionStart < start) {
285
+ inst._field = field;
286
+ break;
287
+ }
288
+ }
289
+ }
290
+ }
291
+ $.data(input, PROP_NAME, inst);
292
+ $.timeEntry._showField(inst);
293
+ $.timeEntry._focussed = false;
294
+ },
295
+
296
+ /* Handle keystrokes in the field.
297
+ @param event (event) the keydown event
298
+ @return (boolean) true to continue, false to stop processing */
299
+ _doKeyDown: function(event) {
300
+ if (event.keyCode >= 48) { // >= '0'
301
+ return true;
302
+ }
303
+ var inst = $.data(event.target, PROP_NAME);
304
+ switch (event.keyCode) {
305
+ case 9: return (event.shiftKey ?
306
+ // move to previous time field, or out if at the beginning
307
+ $.timeEntry._previousField(inst, true) :
308
+ // move to next time field, or out if at the end
309
+ $.timeEntry._nextField(inst, true));
310
+ case 35: if (event.ctrlKey) { // clear time on ctrl+end
311
+ $.timeEntry._setValue(inst, '');
312
+ }
313
+ else { // last field on end
314
+ inst._field = Math.max(1, inst._secondField, inst._ampmField);
315
+ $.timeEntry._adjustField(inst, 0);
316
+ }
317
+ break;
318
+ case 36: if (event.ctrlKey) { // current time on ctrl+home
319
+ $.timeEntry._setTime(inst);
320
+ }
321
+ else { // first field on home
322
+ inst._field = 0;
323
+ $.timeEntry._adjustField(inst, 0);
324
+ }
325
+ break;
326
+ case 37: $.timeEntry._previousField(inst, false); break; // previous field on left
327
+ case 38: $.timeEntry._adjustField(inst, +1); break; // increment time field on up
328
+ case 39: $.timeEntry._nextField(inst, false); break; // next field on right
329
+ case 40: $.timeEntry._adjustField(inst, -1); break; // decrement time field on down
330
+ case 46: $.timeEntry._setValue(inst, ''); break; // clear time on delete
331
+ }
332
+ return false;
333
+ },
334
+
335
+ /* Disallow unwanted characters.
336
+ @param event (event) the keypress event
337
+ @return (boolean) true to continue, false to stop processing */
338
+ _doKeyPress: function(event) {
339
+ var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
340
+ if (chr < ' ') {
341
+ return true;
342
+ }
343
+ var inst = $.data(event.target, PROP_NAME);
344
+ $.timeEntry._handleKeyPress(inst, chr);
345
+ return false;
346
+ },
347
+
348
+ /* Increment/decrement on mouse wheel activity.
349
+ @param event (event) the mouse wheel event
350
+ @param delta (number) the amount of change */
351
+ _doMouseWheel: function(event, delta) {
352
+ if ($.timeEntry._isDisabledTimeEntry(event.target)) {
353
+ return;
354
+ }
355
+ delta = ($.browser.opera ? -delta / Math.abs(delta) :
356
+ ($.browser.safari ? delta / Math.abs(delta) : delta));
357
+ var inst = $.data(event.target, PROP_NAME);
358
+ $.timeEntry._adjustField(inst, delta);
359
+ event.preventDefault();
360
+ },
361
+
362
+ /* Change the title based on position within the spinner.
363
+ @param event (event) the mouse move event */
364
+ _describeSpinner: function(event) {
365
+ var spinner = $.timeEntry._getSpinnerTarget(event);
366
+ var inst = $.data(spinner.previousSibling, PROP_NAME);
367
+ spinner.title = $.timeEntry._get(inst, 'spinnerTexts')[$.timeEntry._getSpinnerRegion(inst, event)];
368
+ },
369
+
370
+ /* Handle a click on the spinner.
371
+ @param event (event) the mouse click event */
372
+ _handleSpinner: function(event) {
373
+ var spinner = $.timeEntry._getSpinnerTarget(event);
374
+ var input = spinner.previousSibling;
375
+ if ($.timeEntry._isDisabledTimeEntry(input)) {
376
+ return;
377
+ }
378
+ if (input == $.timeEntry._blurredInput) {
379
+ $.timeEntry._lastInput = input;
380
+ $.timeEntry._blurredInput = null;
381
+ }
382
+ var inst = $.data(input, PROP_NAME);
383
+ $.timeEntry._doFocus(input);
384
+ var region = $.timeEntry._getSpinnerRegion(inst, event);
385
+ $.timeEntry._changeSpinner(inst, spinner, region);
386
+ $.timeEntry._actionSpinner(inst, region);
387
+ $.timeEntry._timer = null;
388
+ var spinnerRepeat = $.timeEntry._get(inst, 'spinnerRepeat');
389
+ if (region >= 3 && spinnerRepeat[0]) { // repeat increment/decrement
390
+ $.timeEntry._timer = setTimeout(
391
+ function() { $.timeEntry._repeatSpinner(inst, region); },
392
+ spinnerRepeat[0]);
393
+ $(spinner).one('mouseout', $.timeEntry._releaseSpinner).
394
+ one('mouseup', $.timeEntry._releaseSpinner);
395
+ }
396
+ },
397
+
398
+ /* Action a click on the spinner.
399
+ @param inst (object) the instance settings
400
+ @param region (number) the spinner "button" */
401
+ _actionSpinner: function(inst, region) {
402
+ switch (region) {
403
+ case 0: this._setTime(inst); break;
404
+ case 1: this._previousField(inst, false); break;
405
+ case 2: this._nextField(inst, false); break;
406
+ case 3: this._adjustField(inst, +1); break;
407
+ case 4: this._adjustField(inst, -1); break;
408
+ }
409
+ },
410
+
411
+ /* Repeat a click on the spinner.
412
+ @param inst (object) the instance settings
413
+ @param region (number) the spinner "button" */
414
+ _repeatSpinner: function(inst, region) {
415
+ if (!$.timeEntry._timer) {
416
+ return;
417
+ }
418
+ $.timeEntry._lastInput = $.timeEntry._blurredInput;
419
+ this._actionSpinner(inst, region);
420
+ this._timer = setTimeout(
421
+ function() { $.timeEntry._repeatSpinner(inst, region); },
422
+ this._get(inst, 'spinnerRepeat')[1]);
423
+ },
424
+
425
+ /* Stop a spinner repeat.
426
+ @param event (event) the mouse event */
427
+ _releaseSpinner: function(event) {
428
+ clearTimeout($.timeEntry._timer);
429
+ $.timeEntry._timer = null;
430
+ },
431
+
432
+ /* Tidy up after a spinner click.
433
+ @param event (event) the mouse event */
434
+ _endSpinner: function(event) {
435
+ $.timeEntry._timer = null;
436
+ var spinner = $.timeEntry._getSpinnerTarget(event);
437
+ var input = spinner.previousSibling;
438
+ var inst = $.data(input, PROP_NAME);
439
+ if (!$.timeEntry._isDisabledTimeEntry(input)) {
440
+ $.timeEntry._changeSpinner(inst, spinner, -1);
441
+ }
442
+ if (!$.browser.opera) {
443
+ $.timeEntry._lastInput = $.timeEntry._blurredInput;
444
+ }
445
+ if ($.timeEntry._lastInput) {
446
+ $.timeEntry._showField(inst);
447
+ }
448
+ },
449
+
450
+ /* Retrieve the spinner from the event.
451
+ @param event (event) the mouse click event
452
+ @return (element) the target field */
453
+ _getSpinnerTarget: function(event) {
454
+ return event.target || event.srcElement;
455
+ },
456
+
457
+ /* Determine which "button" within the spinner was clicked.
458
+ @param inst (object) the instance settings
459
+ @param event (event) the mouse event
460
+ @return (number) the spinner "button" number */
461
+ _getSpinnerRegion: function(inst, event) {
462
+ var spinner = this._getSpinnerTarget(event);
463
+ var pos = ($.browser.opera || $.browser.safari ?
464
+ $.timeEntry._findPos(spinner) : $(spinner).offset());
465
+ var scrolled = ($.browser.safari ? $.timeEntry._findScroll(spinner) :
466
+ [document.documentElement.scrollLeft || document.body.scrollLeft,
467
+ document.documentElement.scrollTop || document.body.scrollTop]);
468
+ var spinnerIncDecOnly = this._get(inst, 'spinnerIncDecOnly');
469
+ var left = (spinnerIncDecOnly ? 99 :
470
+ event.clientX + scrolled[0] - pos.left - ($.browser.msie ? 1 : 0));
471
+ var top = event.clientY + scrolled[1] - pos.top - ($.browser.msie ? 1 : 0);
472
+ var spinnerSize = this._get(inst, 'spinnerSize');
473
+ var right = (spinnerIncDecOnly ? 99 : spinnerSize[0] - left);
474
+ var bottom = spinnerSize[1] - top;
475
+ if (spinnerSize[2] > 0 && Math.abs(left - right) <= spinnerSize[2] &&
476
+ Math.abs(top - bottom) <= spinnerSize[2]) {
477
+ return 0; // centre button
478
+ }
479
+ var min = Math.min(left, top, right, bottom);
480
+ return (min == left ? 1 : (min == right ? 2 : (min == top ? 3 : 4))); // nearest edge
481
+ },
482
+
483
+ /* Change the spinner image depending on button clicked.
484
+ @param inst (object) the instance settings
485
+ @param spinner (element) the spinner control
486
+ @param region (number) the spinner "button" */
487
+ _changeSpinner: function(inst, spinner, region) {
488
+ $(spinner).css('background-position',
489
+ '-' + ((region + 1) * this._get(inst, 'spinnerSize')[0]) + 'px 0px');
490
+ },
491
+
492
+ /* Find an object's position on the screen.
493
+ @param obj (element) the control
494
+ @return (object) position as .left and .top */
495
+ _findPos: function(obj) {
496
+ var curLeft = curTop = 0;
497
+ if (obj.offsetParent) {
498
+ curLeft = obj.offsetLeft;
499
+ curTop = obj.offsetTop;
500
+ while (obj = obj.offsetParent) {
501
+ var origCurLeft = curLeft;
502
+ curLeft += obj.offsetLeft;
503
+ if (curLeft < 0) {
504
+ curLeft = origCurLeft;
505
+ }
506
+ curTop += obj.offsetTop;
507
+ }
508
+ }
509
+ return {left: curLeft, top: curTop};
510
+ },
511
+
512
+ /* Find an object's scroll offset on the screen.
513
+ @param obj (element) the control
514
+ @return (number[]) offset as [left, top] */
515
+ _findScroll: function(obj) {
516
+ var isFixed = false;
517
+ $(obj).parents().each(function() {
518
+ isFixed |= $(this).css('position') == 'fixed';
519
+ });
520
+ if (isFixed) {
521
+ return [0, 0];
522
+ }
523
+ var scrollLeft = obj.scrollLeft;
524
+ var scrollTop = obj.scrollTop;
525
+ while (obj = obj.parentNode) {
526
+ scrollLeft += obj.scrollLeft || 0;
527
+ scrollTop += obj.scrollTop || 0;
528
+ }
529
+ return [scrollLeft, scrollTop];
530
+ },
531
+
532
+ /* Get a setting value, defaulting if necessary.
533
+ @param inst (object) the instance settings
534
+ @param name (string) the setting name
535
+ @return (any) the setting value */
536
+ _get: function(inst, name) {
537
+ return (inst.options[name] != null ?
538
+ inst.options[name] : $.timeEntry._defaults[name]);
539
+ },
540
+
541
+ /* Extract the time value from the input field, or default to now.
542
+ @param inst (object) the instance settings */
543
+ _parseTime: function(inst) {
544
+ var currentTime = this._extractTime(inst);
545
+ var showSeconds = this._get(inst, 'showSeconds');
546
+ if (currentTime) {
547
+ inst._selectedHour = currentTime[0];
548
+ inst._selectedMinute = currentTime[1];
549
+ inst._selectedSecond = currentTime[2];
550
+ }
551
+ else {
552
+ var now = this._constrainTime(inst);
553
+ inst._selectedHour = now[0];
554
+ inst._selectedMinute = now[1];
555
+ inst._selectedSecond = (showSeconds ? now[2] : 0);
556
+ }
557
+ inst._secondField = (showSeconds ? 2 : -1);
558
+ inst._ampmField = (this._get(inst, 'show24Hours') ? -1 : (showSeconds ? 3 : 2));
559
+ inst._lastChr = '';
560
+ inst._field = Math.max(0, Math.min(
561
+ Math.max(1, inst._secondField, inst._ampmField), this._get(inst, 'initialField')));
562
+ if (inst.input.val() != '') {
563
+ this._showTime(inst);
564
+ }
565
+ },
566
+
567
+ /* Extract the time value from the input field as an array of values, or default to null.
568
+ @param inst (object) the instance settings
569
+ @return (number[3]) the time components (hours, minutes, seconds)
570
+ or null if no value */
571
+ _extractTime: function(inst) {
572
+ var value = inst.input.val();
573
+ var separator = this._get(inst, 'separator');
574
+ var currentTime = value.split(separator);
575
+ if (separator == '' && value != '') {
576
+ currentTime[0] = value.substring(0, 2);
577
+ currentTime[1] = value.substring(2, 4);
578
+ currentTime[2] = value.substring(4, 6);
579
+ }
580
+ var ampmNames = this._get(inst, 'ampmNames');
581
+ var show24Hours = this._get(inst, 'show24Hours');
582
+ if (currentTime.length >= 2) {
583
+ var isAM = !show24Hours && (value.indexOf(ampmNames[0]) > -1);
584
+ var isPM = !show24Hours && (value.indexOf(ampmNames[1]) > -1);
585
+ var hour = parseInt(currentTime[0], 10);
586
+ hour = (isNaN(hour) ? 0 : hour);
587
+ hour = ((isAM || isPM) && hour == 12 ? 0 : hour) + (isPM ? 12 : 0);
588
+ var minute = parseInt(currentTime[1], 10);
589
+ minute = (isNaN(minute) ? 0 : minute);
590
+ var second = (currentTime.length >= 3 ?
591
+ parseInt(currentTime[2], 10) : 0);
592
+ second = (isNaN(second) || !this._get(inst, 'showSeconds') ? 0 : second);
593
+ return this._constrainTime(inst, [hour, minute, second]);
594
+ }
595
+ return null;
596
+ },
597
+
598
+ /* Constrain the given/current time to the time steps.
599
+ @param inst (object) the instance settings
600
+ @param fields (number[3]) the current time components (hours, minutes, seconds)
601
+ @return (number[3]) the constrained time components (hours, minutes, seconds) */
602
+ _constrainTime: function(inst, fields) {
603
+ var specified = (fields != null);
604
+ if (!specified) {
605
+ var now = this._determineTime(this._get(inst, 'defaultTime')) || new Date();
606
+ fields = [now.getHours(), now.getMinutes(), now.getSeconds()];
607
+ }
608
+ var reset = false;
609
+ var timeSteps = this._get(inst, 'timeSteps');
610
+ for (var i = 0; i < timeSteps.length; i++) {
611
+ if (reset) {
612
+ fields[i] = 0;
613
+ }
614
+ else if (timeSteps[i] > 1) {
615
+ fields[i] = Math.round(fields[i] / timeSteps[i]) * timeSteps[i];
616
+ reset = true;
617
+ }
618
+ }
619
+ return fields;
620
+ },
621
+
622
+ /* Set the selected time into the input field.
623
+ @param inst (object) the instance settings */
624
+ _showTime: function(inst) {
625
+ var show24Hours = this._get(inst, 'show24Hours');
626
+ var separator = this._get(inst, 'separator');
627
+ var currentTime = (this._formatNumber(show24Hours ? inst._selectedHour :
628
+ ((inst._selectedHour + 11) % 12) + 1) + separator +
629
+ this._formatNumber(inst._selectedMinute) +
630
+ (this._get(inst, 'showSeconds') ? separator +
631
+ this._formatNumber(inst._selectedSecond) : '') +
632
+ (show24Hours ? '' : this._get(inst, 'ampmPrefix') +
633
+ this._get(inst, 'ampmNames')[(inst._selectedHour < 12 ? 0 : 1)]));
634
+ this._setValue(inst, currentTime);
635
+ this._showField(inst);
636
+ },
637
+
638
+ /* Highlight the current time field.
639
+ @param inst (object) the instance settings */
640
+ _showField: function(inst) {
641
+ if (inst.input.is(':hidden')) {
642
+ return;
643
+ }
644
+ var input = inst.input[0];
645
+ var separator = this._get(inst, 'separator');
646
+ var fieldSize = separator.length + 2;
647
+ var start = (inst._field != inst._ampmField ? (inst._field * fieldSize) :
648
+ (inst._ampmField * fieldSize) - separator.length + this._get(inst, 'ampmPrefix').length);
649
+ var end = start + (inst._field != inst._ampmField ? 2 : this._get(inst, 'ampmNames')[0].length);
650
+ if (input.setSelectionRange) { // Mozilla
651
+ input.setSelectionRange(start, end);
652
+ }
653
+ else if (input.createTextRange) { // IE
654
+ var range = input.createTextRange();
655
+ range.moveStart('character', start);
656
+ range.moveEnd('character', end - inst.input.val().length);
657
+ range.select();
658
+ }
659
+ if (!input.disabled && $.timeEntry._lastInput == input) {
660
+ input.focus();
661
+ }
662
+ },
663
+
664
+ /* Ensure displayed single number has a leading zero.
665
+ @param value (number) current value
666
+ @return (string) number with at least two digits */
667
+ _formatNumber: function(value) {
668
+ return (value < 10 ? '0' : '') + value;
669
+ },
670
+
671
+ /* Update the input field and notify listeners.
672
+ @param inst (object) the instance settings
673
+ @param value (string) the new value */
674
+ _setValue: function(inst, value) {
675
+ inst.input.val(value).trigger('change');
676
+ },
677
+
678
+ /* Move to previous field, or out of field altogether if appropriate.
679
+ @param inst (object) the instance settings
680
+ @param moveOut (boolean) true if can move out of the field
681
+ @return (boolean) true if exitting the field, false if not */
682
+ _previousField: function(inst, moveOut) {
683
+ var atFirst = (inst.input.val() == '' || inst._field == 0);
684
+ if (!atFirst) {
685
+ inst._field--;
686
+ }
687
+ this._showField(inst);
688
+ inst._lastChr = '';
689
+ $.data(inst.input[0], PROP_NAME, inst);
690
+ return (atFirst && moveOut);
691
+ },
692
+
693
+ /* Move to next field, or out of field altogether if appropriate.
694
+ @param inst (object) the instance settings
695
+ @param moveOut (boolean) true if can move out of the field
696
+ @return (boolean) true if exitting the field, false if not */
697
+ _nextField: function(inst, moveOut) {
698
+ var atLast = (inst.input.val() == '' ||
699
+ inst._field == Math.max(1, inst._secondField, inst._ampmField));
700
+ if (!atLast) {
701
+ inst._field++;
702
+ }
703
+ this._showField(inst);
704
+ inst._lastChr = '';
705
+ $.data(inst.input[0], PROP_NAME, inst);
706
+ return (atLast && moveOut);
707
+ },
708
+
709
+ /* Update the current field in the direction indicated.
710
+ @param inst (object) the instance settings
711
+ @param offset (number) the amount to change by */
712
+ _adjustField: function(inst, offset) {
713
+ if (inst.input.val() == '') {
714
+ offset = 0;
715
+ }
716
+ var timeSteps = this._get(inst, 'timeSteps');
717
+ this._setTime(inst, new Date(0, 0, 0,
718
+ inst._selectedHour + (inst._field == 0 ? offset * timeSteps[0] : 0) +
719
+ (inst._field == inst._ampmField ? offset * 12 : 0),
720
+ inst._selectedMinute + (inst._field == 1 ? offset * timeSteps[1] : 0),
721
+ inst._selectedSecond + (inst._field == inst._secondField ? offset * timeSteps[2] : 0)));
722
+ },
723
+
724
+ /* Check against minimum/maximum and display time.
725
+ @param inst (object) the instance settings
726
+ @param time (Date) an actual time or
727
+ (number) offset in seconds from now or
728
+ (string) units and periods of offsets from now */
729
+ _setTime: function(inst, time) {
730
+ time = this._determineTime(time);
731
+ var fields = this._constrainTime(inst, time ?
732
+ [time.getHours(), time.getMinutes(), time.getSeconds()] : null);
733
+ time = new Date(0, 0, 0, fields[0], fields[1], fields[2]);
734
+ // normalise to base date
735
+ var time = this._normaliseTime(time);
736
+ var minTime = this._normaliseTime(this._determineTime(this._get(inst, 'minTime')));
737
+ var maxTime = this._normaliseTime(this._determineTime(this._get(inst, 'maxTime')));
738
+ // ensure it is within the bounds set
739
+ time = (minTime && time < minTime ? minTime :
740
+ (maxTime && time > maxTime ? maxTime : time));
741
+ var beforeSetTime = this._get(inst, 'beforeSetTime');
742
+ // perform further restrictions if required
743
+ if (beforeSetTime) {
744
+ time = beforeSetTime.apply(inst.input[0],
745
+ [this._getTimeTimeEntry(inst.input[0]), time, minTime, maxTime]);
746
+ }
747
+ inst._selectedHour = time.getHours();
748
+ inst._selectedMinute = time.getMinutes();
749
+ inst._selectedSecond = time.getSeconds();
750
+ this._showTime(inst);
751
+ $.data(inst.input[0], PROP_NAME, inst);
752
+ },
753
+
754
+ /* A time may be specified as an exact value or a relative one.
755
+ @param setting (Date) an actual time or
756
+ (number) offset in seconds from now or
757
+ (string) units and periods of offsets from now
758
+ @return (Date) the calculated time */
759
+ _determineTime: function(setting) {
760
+ var offsetNumeric = function(offset) { // e.g. +300, -2
761
+ var time = new Date();
762
+ time.setTime(time.getTime() + offset * 1000);
763
+ return time;
764
+ };
765
+ var offsetString = function(offset) { // e.g. '+2m', '-4h', '+3h +30m'
766
+ var time = new Date();
767
+ var hour = time.getHours();
768
+ var minute = time.getMinutes();
769
+ var second = time.getSeconds();
770
+ var pattern = /([+-]?[0-9]+)\s*(s|S|m|M|h|H)?/g;
771
+ var matches = pattern.exec(offset);
772
+ while (matches) {
773
+ switch (matches[2] || 's') {
774
+ case 's' : case 'S' :
775
+ second += parseInt(matches[1], 10); break;
776
+ case 'm' : case 'M' :
777
+ minute += parseInt(matches[1], 10); break;
778
+ case 'h' : case 'H' :
779
+ hour += parseInt(matches[1], 10); break;
780
+ }
781
+ matches = pattern.exec(offset);
782
+ }
783
+ time = new Date(0, 0, 10, hour, minute, second, 0);
784
+ if (/^!/.test(offset)) { // no wrapping
785
+ if (time.getDate() > 10) {
786
+ time = new Date(0, 0, 10, 23, 59, 59);
787
+ }
788
+ else if (time.getDate() < 10) {
789
+ time = new Date(0, 0, 10, 0, 0, 0);
790
+ }
791
+ }
792
+ return time;
793
+ };
794
+ return (setting ? (typeof setting == 'string' ? offsetString(setting) :
795
+ (typeof setting == 'number' ? offsetNumeric(setting) : setting)) : null);
796
+ },
797
+
798
+ /* Normalise time object to a common date.
799
+ @param time (Date) the original time
800
+ @return (Date) the normalised time */
801
+ _normaliseTime: function(time) {
802
+ if (!time) {
803
+ return null;
804
+ }
805
+ time.setFullYear(1900);
806
+ time.setMonth(0);
807
+ time.setDate(0);
808
+ return time;
809
+ },
810
+
811
+ /* Update time based on keystroke entered.
812
+ @param inst (object) the instance settings
813
+ @param chr (ch) the new character */
814
+ _handleKeyPress: function(inst, chr) {
815
+ if (chr == this._get(inst, 'separator')) {
816
+ this._nextField(inst, false);
817
+ }
818
+ else if (chr >= '0' && chr <= '9') { // allow direct entry of time
819
+ var value = parseInt(inst._lastChr + chr, 10);
820
+ var show24Hours = this._get(inst, 'show24Hours');
821
+ var hour = (inst._field == 0 && ((show24Hours && value < 24) ||
822
+ (value >= 1 && value <= 12)) ?
823
+ value + (!show24Hours && inst._selectedHour >= 12 ? 12 : 0) : inst._selectedHour);
824
+ var minute = (inst._field == 1 && value < 60 ? value : inst._selectedMinute);
825
+ var second = (inst._field == inst._secondField && value < 60 ?
826
+ value : inst._selectedSecond);
827
+ var fields = this._constrainTime(inst, [hour, minute, second]);
828
+ this._setTime(inst, new Date(0, 0, 0, fields[0], fields[1], fields[2]));
829
+ inst._lastChr = chr;
830
+ }
831
+ else if (!this._get(inst, 'show24Hours')) { // set am/pm based on first char of names
832
+ var ampmNames = this._get(inst, 'ampmNames');
833
+ if ((chr == ampmNames[0].substring(0, 1).toLowerCase() &&
834
+ inst._selectedHour >= 12) ||
835
+ (chr == ampmNames[1].substring(0, 1).toLowerCase() &&
836
+ inst._selectedHour < 12)) {
837
+ var saveField = inst._field;
838
+ inst._field = inst._ampmField;
839
+ this._adjustField(inst, +1);
840
+ inst._field = saveField;
841
+ this._showField(inst);
842
+ }
843
+ }
844
+ }
845
+ });
846
+
847
+ /* jQuery extend now ignores nulls!
848
+ @param target (object) the object to update
849
+ @param props (object) the new settings
850
+ @return (object) the updated object */
851
+ function extendRemove(target, props) {
852
+ $.extend(target, props);
853
+ for (var name in props) {
854
+ if (props[name] == null) {
855
+ target[name] = null;
856
+ }
857
+ }
858
+ return target;
859
+ }
860
+
861
+ /* Attach the time entry functionality to a jQuery selection.
862
+ @param command (string) the command to run (optional, default 'attach')
863
+ @param options (object) the new settings to use for these countdown instances (optional)
864
+ @return (jQuery) for chaining further calls */
865
+ $.fn.timeEntry = function(options) {
866
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
867
+ if (typeof options == 'string' && (options == 'isDisabled' || options == 'getTime')) {
868
+ return $.timeEntry['_' + options + 'TimeEntry'].apply($.timeEntry, [this[0]].concat(otherArgs));
869
+ }
870
+ return this.each(function() {
871
+ var nodeName = this.nodeName.toLowerCase();
872
+ if (nodeName == 'input') {
873
+ if (typeof options == 'string') {
874
+ $.timeEntry['_' + options + 'TimeEntry'].apply($.timeEntry, [this].concat(otherArgs));
875
+ }
876
+ else {
877
+ // check for settings on the control itself - in namespace 'time:'
878
+ var inlineSettings = {};
879
+ for (attrName in $.timeEntry._defaults) {
880
+ var attrValue = this.getAttribute('time:' + attrName);
881
+ if (attrValue) {
882
+ inlineSettings = inlineSettings || {};
883
+ try {
884
+ inlineSettings[attrName] = eval(attrValue);
885
+ }
886
+ catch (err) {
887
+ inlineSettings[attrName] = attrValue;
888
+ }
889
+ }
890
+ }
891
+ $.timeEntry._connectTimeEntry(this, $.extend(inlineSettings, options));
892
+ }
893
+ }
894
+ });
895
+ };
896
+
897
+ /* Initialise the time entry functionality. */
898
+ $.timeEntry = new TimeEntry(); // singleton instance
899
+
900
+ })(jQuery);
js/timeentry/jquery.timeentry.min.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Time entry for jQuery v1.4.2.
3
+ Written by Keith Wood (kbwood@virginbroadband.com.au) June 2007.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+ (function($){function TimeEntry(){this._disabledInputs=[];this.regional=[];this.regional['']={show24Hours:false,separator:':',ampmPrefix:'',ampmNames:['AM','PM'],spinnerTexts:['Now','Previous field','Next field','Increment','Decrement']};this._defaults={appendText:'',showSeconds:false,timeSteps:[1,1,1],initialField:0,useMouseWheel:true,defaultTime:null,minTime:null,maxTime:null,spinnerImage:'timeEntry.png',spinnerSize:[20,20,8],spinnerIncDecOnly:false,spinnerRepeat:[500,250],beforeShow:null,beforeSetTime:null};$.extend(this._defaults,this.regional[''])}var m='timeEntry';$.extend(TimeEntry.prototype,{markerClassName:'hasTimeEntry',setDefaults:function(a){extendRemove(this._defaults,a||{})},_connectTimeEntry:function(b,c){var d=$(b);if(d.hasClass(this.markerClassName)){return}var e={};e.options=$.extend({},c);e._selectedHour=0;e._selectedMinute=0;e._selectedSecond=0;e._field=0;e.input=$(b);$.data(b,m,e);var f=this._get(e,'spinnerImage');var g=this._get(e,'spinnerText');var h=this._get(e,'spinnerSize');var i=this._get(e,'appendText');var j=(!f?null:$('<span class="timeEntry_control" style="display: inline-block; '+'background: url(\''+f+'\') 0 0 no-repeat; '+'width: '+h[0]+'px; height: '+h[1]+'px;'+($.browser.mozilla&&$.browser.version<'1.9'?' padding-left: '+h[0]+'px; padding-bottom: '+(h[1]-18)+'px;':'')+'"></span>'));d.wrap('<span class="timeEntry_wrap"></span>').after(i?'<span class="timeEntry_append">'+i+'</span>':'').after(j||'');d.addClass(this.markerClassName).bind('focus.timeEntry',this._doFocus).bind('blur.timeEntry',this._doBlur).bind('click.timeEntry',this._doClick).bind('keydown.timeEntry',this._doKeyDown).bind('keypress.timeEntry',this._doKeyPress);if($.browser.mozilla){d.bind('input.timeEntry',function(a){$.timeentry._parseTime(e)})}if($.browser.msie){d.bind('paste.timeEntry',function(a){setTimeout(function(){$.timeentry._parseTime(e)},1)})}if(this._get(e,'useMouseWheel')&&$.fn.mousewheel){d.mousewheel(this._doMouseWheel)}if(j){j.mousedown(this._handleSpinner).mouseup(this._endSpinner).mouseout(this._endSpinner).mousemove(this._describeSpinner)}},_enableTimeEntry:function(a){this._enableDisable(a,false)},_disableTimeEntry:function(a){this._enableDisable(a,true)},_enableDisable:function(b,c){var d=$.data(b,m);if(!d){return}b.disabled=c;if(b.nextSibling&&b.nextSibling.nodeName.toLowerCase()=='span'){$.timeEntry._changeSpinner(d,b.nextSibling,(c?5:-1))}$.timeEntry._disabledInputs=$.map($.timeEntry._disabledInputs,function(a){return(a==b?null:a)});if(c){$.timeEntry._disabledInputs.push(b)}},_isDisabledTimeEntry:function(a){return $.inArray(a,this._disabledInputs)>-1},_changeTimeEntry:function(a,b){var c=$.data(a,m);if(c){var d=this._extractTime(c);extendRemove(c.options,b||{});if(d){this._setTime(c,new Date(0,0,0,d[0],d[1],d[2]))}}$.data(a,m,c)},_destroyTimeEntry:function(b){$input=$(b);if(!$input.hasClass(this.markerClassName)){return}$input.removeClass(this.markerClassName).unbind('focus.timeEntry').unbind('blur.timeEntry').unbind('click.timeEntry').unbind('keydown.timeEntry').unbind('keypress.timeEntry');if($.browser.mozilla){$input.unbind('input.timeEntry')}if($.browser.msie){$input.unbind('paste.timeEntry')}if($.fn.mousewheel){$input.unmousewheel()}this._disabledInputs=$.map(this._disabledInputs,function(a){return(a==b?null:a)});$input.parent().replaceWith($input);$.removeData(b,m)},_setTimeTimeEntry:function(a,b){var c=$.data(a,m);if(c){this._setTime(c,b?(typeof b=='object'?new Date(b.getTime()):b):null)}},_getTimeTimeEntry:function(a){var b=$.data(a,m);var c=(b?this._extractTime(b):null);return(!c?null:new Date(0,0,0,c[0],c[1],c[2]))},_doFocus:function(a){var b=(a.nodeName&&a.nodeName.toLowerCase()=='input'?a:this);if($.timeEntry._lastInput==b){return}if($.timeEntry._isDisabledTimeEntry(b)){return}var c=$.data(b,m);$.timeEntry._focussed=true;$.timeEntry._lastInput=b;$.timeEntry._blurredInput=null;var d=$.timeEntry._get(c,'beforeShow');extendRemove(c.options,(d?d.apply(b,[b]):{}));$.data(b,m,c);$.timeEntry._parseTime(c)},_doBlur:function(a){$.timeEntry._blurredInput=$.timeEntry._lastInput;$.timeEntry._lastInput=null},_doClick:function(a){var b=a.target;var c=$.data(b,m);if(!$.timeEntry._focussed){var d=$.timeEntry._get(c,'separator').length+2;c._field=0;if($.browser.msie){var e=b.value;var f=a.clientX+document.documentElement.scrollLeft-$(a.srcElement).offset().left;for(var g=0;g<=Math.max(1,c._secondField,c._ampmField);g++){var h=(g!=c._ampmField?(g*d)+2:(c._ampmField*d)+$.timeEntry._get(c,'ampmPrefix').length+$.timeEntry._get(c,'ampmNames')[0].length);b.value=e.substring(0,h);var i=b.createTextRange();if(f<i.boundingWidth){c._field=g;break}}b.value=e}else{for(var g=0;g<=Math.max(1,c._secondField,c._ampmField);g++){var j=(g!=c._ampmField?(g*d)+2:(c._ampmField*d)+$.timeEntry._get(c,'ampmPrefix').length+$.timeEntry._get(c,'ampmNames')[0].length);if(b.selectionStart<j){c._field=g;break}}}}$.data(b,m,c);$.timeEntry._showField(c);$.timeEntry._focussed=false},_doKeyDown:function(a){if(a.keyCode>=48){return true}var b=$.data(a.target,m);switch(a.keyCode){case 9:return(a.shiftKey?$.timeEntry._previousField(b,true):$.timeEntry._nextField(b,true));case 35:if(a.ctrlKey){$.timeEntry._setValue(b,'')}else{b._field=Math.max(1,b._secondField,b._ampmField);$.timeEntry._adjustField(b,0)}break;case 36:if(a.ctrlKey){$.timeEntry._setTime(b)}else{b._field=0;$.timeEntry._adjustField(b,0)}break;case 37:$.timeEntry._previousField(b,false);break;case 38:$.timeEntry._adjustField(b,+1);break;case 39:$.timeEntry._nextField(b,false);break;case 40:$.timeEntry._adjustField(b,-1);break;case 46:$.timeEntry._setValue(b,'');break}return false},_doKeyPress:function(a){var b=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);if(b<' '){return true}var c=$.data(a.target,m);$.timeEntry._handleKeyPress(c,b);return false},_doMouseWheel:function(a,b){if($.timeEntry._isDisabledTimeEntry(a.target)){return}b=($.browser.opera?-b/Math.abs(b):($.browser.safari?b/Math.abs(b):b));var c=$.data(a.target,m);$.timeEntry._adjustField(c,b);a.preventDefault()},_describeSpinner:function(a){var b=$.timeEntry._getSpinnerTarget(a);var c=$.data(b.previousSibling,m);b.title=$.timeEntry._get(c,'spinnerTexts')[$.timeEntry._getSpinnerRegion(c,a)]},_handleSpinner:function(a){var b=$.timeEntry._getSpinnerTarget(a);var c=b.previousSibling;if($.timeEntry._isDisabledTimeEntry(c)){return}if(c==$.timeEntry._blurredInput){$.timeEntry._lastInput=c;$.timeEntry._blurredInput=null}var d=$.data(c,m);$.timeEntry._doFocus(c);var e=$.timeEntry._getSpinnerRegion(d,a);$.timeEntry._changeSpinner(d,b,e);$.timeEntry._actionSpinner(d,e);$.timeEntry._timer=null;var f=$.timeEntry._get(d,'spinnerRepeat');if(e>=3&&f[0]){$.timeEntry._timer=setTimeout(function(){$.timeEntry._repeatSpinner(d,e)},f[0]);$(b).one('mouseout',$.timeEntry._releaseSpinner).one('mouseup',$.timeEntry._releaseSpinner)}},_actionSpinner:function(a,b){switch(b){case 0:this._setTime(a);break;case 1:this._previousField(a,false);break;case 2:this._nextField(a,false);break;case 3:this._adjustField(a,+1);break;case 4:this._adjustField(a,-1);break}},_repeatSpinner:function(a,b){if(!$.timeEntry._timer){return}$.timeEntry._lastInput=$.timeEntry._blurredInput;this._actionSpinner(a,b);this._timer=setTimeout(function(){$.timeEntry._repeatSpinner(a,b)},this._get(a,'spinnerRepeat')[1])},_releaseSpinner:function(a){clearTimeout($.timeEntry._timer);$.timeEntry._timer=null},_endSpinner:function(a){$.timeEntry._timer=null;var b=$.timeEntry._getSpinnerTarget(a);var c=b.previousSibling;var d=$.data(c,m);if(!$.timeEntry._isDisabledTimeEntry(c)){$.timeEntry._changeSpinner(d,b,-1)}if(!$.browser.opera){$.timeEntry._lastInput=$.timeEntry._blurredInput}if($.timeEntry._lastInput){$.timeEntry._showField(d)}},_getSpinnerTarget:function(a){return a.target||a.srcElement},_getSpinnerRegion:function(a,b){var c=this._getSpinnerTarget(b);var d=($.browser.opera||$.browser.safari?$.timeEntry._findPos(c):$(c).offset());var e=($.browser.safari?$.timeEntry._findScroll(c):[document.documentElement.scrollLeft||document.body.scrollLeft,document.documentElement.scrollTop||document.body.scrollTop]);var f=this._get(a,'spinnerIncDecOnly');var g=(f?99:b.clientX+e[0]-d.left-($.browser.msie?1:0));var h=b.clientY+e[1]-d.top-($.browser.msie?1:0);var i=this._get(a,'spinnerSize');var j=(f?99:i[0]-g);var k=i[1]-h;if(i[2]>0&&Math.abs(g-j)<=i[2]&&Math.abs(h-k)<=i[2]){return 0}var l=Math.min(g,h,j,k);return(l==g?1:(l==j?2:(l==h?3:4)))},_changeSpinner:function(a,b,c){$(b).css('background-position','-'+((c+1)*this._get(a,'spinnerSize')[0])+'px 0px')},_findPos:function(a){var b=curTop=0;if(a.offsetParent){b=a.offsetLeft;curTop=a.offsetTop;while(a=a.offsetParent){var c=b;b+=a.offsetLeft;if(b<0){b=c}curTop+=a.offsetTop}}return{left:b,top:curTop}},_findScroll:function(a){var b=false;$(a).parents().each(function(){b|=$(this).css('position')=='fixed'});if(b){return[0,0]}var c=a.scrollLeft;var d=a.scrollTop;while(a=a.parentNode){c+=a.scrollLeft||0;d+=a.scrollTop||0}return[c,d]},_get:function(a,b){return(a.options[b]!=null?a.options[b]:$.timeEntry._defaults[b])},_parseTime:function(a){var b=this._extractTime(a);var c=this._get(a,'showSeconds');if(b){a._selectedHour=b[0];a._selectedMinute=b[1];a._selectedSecond=b[2]}else{var d=this._constrainTime(a);a._selectedHour=d[0];a._selectedMinute=d[1];a._selectedSecond=(c?d[2]:0)}a._secondField=(c?2:-1);a._ampmField=(this._get(a,'show24Hours')?-1:(c?3:2));a._lastChr='';a._field=Math.max(0,Math.min(Math.max(1,a._secondField,a._ampmField),this._get(a,'initialField')));if(a.input.val()!=''){this._showTime(a)}},_extractTime:function(a){var b=a.input.val();var c=this._get(a,'separator');var d=b.split(c);if(c==''&&b!=''){d[0]=b.substring(0,2);d[1]=b.substring(2,4);d[2]=b.substring(4,6)}var e=this._get(a,'ampmNames');var f=this._get(a,'show24Hours');if(d.length>=2){var g=!f&&(b.indexOf(e[0])>-1);var h=!f&&(b.indexOf(e[1])>-1);var i=parseInt(d[0],10);i=(isNaN(i)?0:i);i=((g||h)&&i==12?0:i)+(h?12:0);var j=parseInt(d[1],10);j=(isNaN(j)?0:j);var k=(d.length>=3?parseInt(d[2],10):0);k=(isNaN(k)||!this._get(a,'showSeconds')?0:k);return this._constrainTime(a,[i,j,k])}return null},_constrainTime:function(a,b){var c=(b!=null);if(!c){var d=this._determineTime(this._get(a,'defaultTime'))||new Date();b=[d.getHours(),d.getMinutes(),d.getSeconds()]}var e=false;var f=this._get(a,'timeSteps');for(var i=0;i<f.length;i++){if(e){b[i]=0}else if(f[i]>1){b[i]=Math.round(b[i]/f[i])*f[i];e=true}}return b},_showTime:function(a){var b=this._get(a,'show24Hours');var c=this._get(a,'separator');var d=(this._formatNumber(b?a._selectedHour:((a._selectedHour+11)%12)+1)+c+this._formatNumber(a._selectedMinute)+(this._get(a,'showSeconds')?c+this._formatNumber(a._selectedSecond):'')+(b?'':this._get(a,'ampmPrefix')+this._get(a,'ampmNames')[(a._selectedHour<12?0:1)]));this._setValue(a,d);this._showField(a)},_showField:function(a){if(a.input.is(':hidden')){return}var b=a.input[0];var c=this._get(a,'separator');var d=c.length+2;var e=(a._field!=a._ampmField?(a._field*d):(a._ampmField*d)-c.length+this._get(a,'ampmPrefix').length);var f=e+(a._field!=a._ampmField?2:this._get(a,'ampmNames')[0].length);if(b.setSelectionRange){b.setSelectionRange(e,f)}else if(b.createTextRange){var g=b.createTextRange();g.moveStart('character',e);g.moveEnd('character',f-a.input.val().length);g.select()}if(!b.disabled&&$.timeEntry._lastInput==b){b.focus()}},_formatNumber:function(a){return(a<10?'0':'')+a},_setValue:function(a,b){a.input.val(b).trigger('change')},_previousField:function(a,b){var c=(a.input.val()==''||a._field==0);if(!c){a._field--}this._showField(a);a._lastChr='';$.data(a.input[0],m,a);return(c&&b)},_nextField:function(a,b){var c=(a.input.val()==''||a._field==Math.max(1,a._secondField,a._ampmField));if(!c){a._field++}this._showField(a);a._lastChr='';$.data(a.input[0],m,a);return(c&&b)},_adjustField:function(a,b){if(a.input.val()==''){b=0}var c=this._get(a,'timeSteps');this._setTime(a,new Date(0,0,0,a._selectedHour+(a._field==0?b*c[0]:0)+(a._field==a._ampmField?b*12:0),a._selectedMinute+(a._field==1?b*c[1]:0),a._selectedSecond+(a._field==a._secondField?b*c[2]:0)))},_setTime:function(a,b){b=this._determineTime(b);var c=this._constrainTime(a,b?[b.getHours(),b.getMinutes(),b.getSeconds()]:null);b=new Date(0,0,0,c[0],c[1],c[2]);var b=this._normaliseTime(b);var d=this._normaliseTime(this._determineTime(this._get(a,'minTime')));var e=this._normaliseTime(this._determineTime(this._get(a,'maxTime')));b=(d&&b<d?d:(e&&b>e?e:b));var f=this._get(a,'beforeSetTime');if(f){b=f.apply(a.input[0],[this._getTimeTimeEntry(a.input[0]),b,d,e])}a._selectedHour=b.getHours();a._selectedMinute=b.getMinutes();a._selectedSecond=b.getSeconds();this._showTime(a);$.data(a.input[0],m,a)},_determineTime:function(h){var i=function(a){var b=new Date();b.setTime(b.getTime()+a*1000);return b};var j=function(a){var b=new Date();var c=b.getHours();var d=b.getMinutes();var e=b.getSeconds();var f=/([+-]?[0-9]+)\s*(s|S|m|M|h|H)?/g;var g=f.exec(a);while(g){switch(g[2]||'s'){case's':case'S':e+=parseInt(g[1],10);break;case'm':case'M':d+=parseInt(g[1],10);break;case'h':case'H':c+=parseInt(g[1],10);break}g=f.exec(a)}b=new Date(0,0,10,c,d,e,0);if(/^!/.test(a)){if(b.getDate()>10){b=new Date(0,0,10,23,59,59)}else if(b.getDate()<10){b=new Date(0,0,10,0,0,0)}}return b};return(h?(typeof h=='string'?j(h):(typeof h=='number'?i(h):h)):null)},_normaliseTime:function(a){if(!a){return null}a.setFullYear(1900);a.setMonth(0);a.setDate(0);return a},_handleKeyPress:function(a,b){if(b==this._get(a,'separator')){this._nextField(a,false)}else if(b>='0'&&b<='9'){var c=parseInt(a._lastChr+b,10);var d=this._get(a,'show24Hours');var e=(a._field==0&&((d&&c<24)||(c>=1&&c<=12))?c+(!d&&a._selectedHour>=12?12:0):a._selectedHour);var f=(a._field==1&&c<60?c:a._selectedMinute);var g=(a._field==a._secondField&&c<60?c:a._selectedSecond);var h=this._constrainTime(a,[e,f,g]);this._setTime(a,new Date(0,0,0,h[0],h[1],h[2]));a._lastChr=b}else if(!this._get(a,'show24Hours')){var i=this._get(a,'ampmNames');if((b==i[0].substring(0,1).toLowerCase()&&a._selectedHour>=12)||(b==i[1].substring(0,1).toLowerCase()&&a._selectedHour<12)){var j=a._field;a._field=a._ampmField;this._adjustField(a,+1);a._field=j;this._showField(a)}}}});function extendRemove(a,b){$.extend(a,b);for(var c in b){if(b[c]==null){a[c]=null}}return a}$.fn.timeEntry=function(d){var e=Array.prototype.slice.call(arguments,1);if(typeof d=='string'&&(d=='isDisabled'||d=='getTime')){return $.timeEntry['_'+d+'TimeEntry'].apply($.timeEntry,[this[0]].concat(e))}return this.each(function(){var a=this.nodeName.toLowerCase();if(a=='input'){if(typeof d=='string'){$.timeEntry['_'+d+'TimeEntry'].apply($.timeEntry,[this].concat(e))}else{var b={};for(attrName in $.timeEntry._defaults){var c=this.getAttribute('time:'+attrName);if(c){b=b||{};try{b[attrName]=eval(c)}catch(err){b[attrName]=c}}}$.timeEntry._connectTimeEntry(this,$.extend(b,d))}}})};$.timeEntry=new TimeEntry()})(jQuery);
js/timeentry/jquery.timeentry.pack.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /* http://keith-wood.name/timeEntry.html
2
+ Time entry for jQuery v1.4.2.
3
+ Written by Keith Wood (kbwood@virginbroadband.com.au) June 2007.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+ eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(q($){q 1c(){n.P=[];n.1P=[];n.1P[\'\']={15:C,16:\':\',1d:\'\',Q:[\'3v\',\'3w\'],2n:[\'3x\',\'3y 2o\',\'3z 2o\',\'3A\',\'3B\']};n.1e={2p:\'\',1v:C,1Q:[1,1,1],2q:0,2r:N,2s:v,2t:v,2u:v,2v:\'o.3C\',1w:[20,20,8],2w:C,1R:[3D,3E],2x:v,2y:v};$.1f(n.1e,n.1P[\'\'])}7 m=\'o\';$.1f(1c.2z,{1g:\'3F\',3G:q(a){1x(n.1e,a||{})},2A:q(b,c){7 d=$(b);p(d.2B(n.1g)){t}7 e={};e.1h=$.1f({},c);e.G=0;e.R=0;e.T=0;e.w=0;e.u=$(b);$.x(b,m,e);7 f=n.r(e,\'2v\');7 g=n.r(e,\'3H\');7 h=n.r(e,\'1w\');7 i=n.r(e,\'2p\');7 j=(!f?v:$(\'<U 1S="3I" 3J="3K: 3L-3M; \'+\'2C: 3N(\\\'\'+f+\'\\\') 0 0 3O-3P; \'+\'3Q: \'+h[0]+\'1i; 3R: \'+h[1]+\'1i;\'+($.A.1T&&$.A.3S<\'1.9\'?\' 2D-1y: \'+h[0]+\'1i; 2D-3T: \'+(h[1]-18)+\'1i;\':\'\')+\'"></U>\'));d.3U(\'<U 1S="3V"></U>\').2E(i?\'<U 1S="3W">\'+i+\'</U>\':\'\').2E(j||\'\');d.3X(n.1g).V(\'1U.o\',n.1V).V(\'2F.o\',n.2G).V(\'2H.o\',n.2I).V(\'2J.o\',n.2K).V(\'2L.o\',n.2M);p($.A.1T){d.V(\'u.o\',q(a){$.2N.1z(e)})}p($.A.1j){d.V(\'2O.o\',q(a){1W(q(){$.2N.1z(e)},1)})}p(n.r(e,\'2r\')&&$.1X.1Y){d.1Y(n.2P)}p(j){j.3Y(n.2Q).2R(n.1Z).2S(n.1Z).3Z(n.2T)}},41:q(a){n.21(a,C)},42:q(a){n.21(a,N)},21:q(b,c){7 d=$.x(b,m);p(!d){t}b.2U=c;p(b.22&&b.22.1A.1k()==\'U\'){$.o.1B(d,b.22,(c?5:-1))}$.o.P=$.2V($.o.P,q(a){t(a==b?v:a)});p(c){$.o.P.43(b)}},1l:q(a){t $.44(a,n.P)>-1},45:q(a,b){7 c=$.x(a,m);p(c){7 d=n.1C(c);1x(c.1h,b||{});p(d){n.W(c,D I(0,0,0,d[0],d[1],d[2]))}}$.x(a,m,c)},47:q(b){$u=$(b);p(!$u.2B(n.1g)){t}$u.49(n.1g).X(\'1U.o\').X(\'2F.o\').X(\'2H.o\').X(\'2J.o\').X(\'2L.o\');p($.A.1T){$u.X(\'u.o\')}p($.A.1j){$u.X(\'2O.o\')}p($.1X.1Y){$u.4a()}n.P=$.2V(n.P,q(a){t(a==b?v:a)});$u.4b().4c($u);$.4d(b,m)},4e:q(a,b){7 c=$.x(a,m);p(c){n.W(c,b?(1m b==\'4f\'?D I(b.25()):b):v)}},2W:q(a){7 b=$.x(a,m);7 c=(b?n.1C(b):v);t(!c?v:D I(0,0,0,c[0],c[1],c[2]))},1V:q(a){7 b=(a.1A&&a.1A.1k()==\'u\'?a:n);p($.o.K==b){t}p($.o.1l(b)){t}7 c=$.x(b,m);$.o.26=N;$.o.K=b;$.o.17=v;7 d=$.o.r(c,\'2x\');1x(c.1h,(d?d.1D(b,[b]):{}));$.x(b,m,c);$.o.1z(c)},2G:q(a){$.o.17=$.o.K;$.o.K=v},2I:q(a){7 b=a.19;7 c=$.x(b,m);p(!$.o.26){7 d=$.o.r(c,\'16\').E+2;c.w=0;p($.A.1j){7 e=b.27;7 f=a.2X+1n.28.1o-$(a.2Y).2Z().1y;1p(7 g=0;g<=F.1a(1,c.O,c.B);g++){7 h=(g!=c.B?(g*d)+2:(c.B*d)+$.o.r(c,\'1d\').E+$.o.r(c,\'Q\')[0].E);b.27=e.1b(0,h);7 i=b.29();p(f<i.4g){c.w=g;z}}b.27=e}J{1p(7 g=0;g<=F.1a(1,c.O,c.B);g++){7 j=(g!=c.B?(g*d)+2:(c.B*d)+$.o.r(c,\'1d\').E+$.o.r(c,\'Q\')[0].E);p(b.4h<j){c.w=g;z}}}}$.x(b,m,c);$.o.Y(c);$.o.26=C},2K:q(a){p(a.2a>=48){t N}7 b=$.x(a.19,m);2b(a.2a){y 9:t(a.4i?$.o.1E(b,N):$.o.1q(b,N));y 35:p(a.30){$.o.1F(b,\'\')}J{b.w=F.1a(1,b.O,b.B);$.o.L(b,0)}z;y 36:p(a.30){$.o.W(b)}J{b.w=0;$.o.L(b,0)}z;y 37:$.o.1E(b,C);z;y 38:$.o.L(b,+1);z;y 39:$.o.1q(b,C);z;y 40:$.o.L(b,-1);z;y 46:$.o.1F(b,\'\');z}t C},2M:q(a){7 b=4j.4k(a.31==4l?a.2a:a.31);p(b<\' \'){t N}7 c=$.x(a.19,m);$.o.32(c,b);t C},2P:q(a,b){p($.o.1l(a.19)){t}b=($.A.2c?-b/F.1G(b):($.A.2d?b/F.1G(b):b));7 c=$.x(a.19,m);$.o.L(c,b);a.4m()},2T:q(a){7 b=$.o.1r(a);7 c=$.x(b.2e,m);b.4n=$.o.r(c,\'2n\')[$.o.2f(c,a)]},2Q:q(a){7 b=$.o.1r(a);7 c=b.2e;p($.o.1l(c)){t}p(c==$.o.17){$.o.K=c;$.o.17=v}7 d=$.x(c,m);$.o.1V(c);7 e=$.o.2f(d,a);$.o.1B(d,b,e);$.o.2g(d,e);$.o.Z=v;7 f=$.o.r(d,\'1R\');p(e>=3&&f[0]){$.o.Z=1W(q(){$.o.2h(d,e)},f[0]);$(b).33(\'2S\',$.o.2i).33(\'2R\',$.o.2i)}},2g:q(a,b){2b(b){y 0:n.W(a);z;y 1:n.1E(a,C);z;y 2:n.1q(a,C);z;y 3:n.L(a,+1);z;y 4:n.L(a,-1);z}},2h:q(a,b){p(!$.o.Z){t}$.o.K=$.o.17;n.2g(a,b);n.Z=1W(q(){$.o.2h(a,b)},n.r(a,\'1R\')[1])},2i:q(a){4o($.o.Z);$.o.Z=v},1Z:q(a){$.o.Z=v;7 b=$.o.1r(a);7 c=b.2e;7 d=$.x(c,m);p(!$.o.1l(c)){$.o.1B(d,b,-1)}p(!$.A.2c){$.o.K=$.o.17}p($.o.K){$.o.Y(d)}},1r:q(a){t a.19||a.2Y},2f:q(a,b){7 c=n.1r(b);7 d=($.A.2c||$.A.2d?$.o.34(c):$(c).2Z());7 e=($.A.2d?$.o.3a(c):[1n.28.1o||1n.3b.1o,1n.28.1H||1n.3b.1H]);7 f=n.r(a,\'2w\');7 g=(f?3c:b.2X+e[0]-d.1y-($.A.1j?1:0));7 h=b.4p+e[1]-d.3d-($.A.1j?1:0);7 i=n.r(a,\'1w\');7 j=(f?3c:i[0]-g);7 k=i[1]-h;p(i[2]>0&&F.1G(g-j)<=i[2]&&F.1G(h-k)<=i[2]){t 0}7 l=F.3e(g,h,j,k);t(l==g?1:(l==j?2:(l==h?3:4)))},1B:q(a,b,c){$(b).3f(\'2C-3g\',\'-\'+((c+1)*n.r(a,\'1w\')[0])+\'1i 4q\')},34:q(a){7 b=1I=0;p(a.3h){b=a.3i;1I=a.3j;2j(a=a.3h){7 c=b;b+=a.3i;p(b<0){b=c}1I+=a.3j}}t{1y:b,3d:1I}},3a:q(a){7 b=C;$(a).4r().3k(q(){b|=$(n).3f(\'3g\')==\'4s\'});p(b){t[0,0]}7 c=a.1o;7 d=a.1H;2j(a=a.4t){c+=a.1o||0;d+=a.1H||0}t[c,d]},r:q(a,b){t(a.1h[b]!=v?a.1h[b]:$.o.1e[b])},1z:q(a){7 b=n.1C(a);7 c=n.r(a,\'1v\');p(b){a.G=b[0];a.R=b[1];a.T=b[2]}J{7 d=n.1s(a);a.G=d[0];a.R=d[1];a.T=(c?d[2]:0)}a.O=(c?2:-1);a.B=(n.r(a,\'15\')?-1:(c?3:2));a.1t=\'\';a.w=F.1a(0,F.3e(F.1a(1,a.O,a.B),n.r(a,\'2q\')));p(a.u.13()!=\'\'){n.2k(a)}},1C:q(a){7 b=a.u.13();7 c=n.r(a,\'16\');7 d=b.4u(c);p(c==\'\'&&b!=\'\'){d[0]=b.1b(0,2);d[1]=b.1b(2,4);d[2]=b.1b(4,6)}7 e=n.r(a,\'Q\');7 f=n.r(a,\'15\');p(d.E>=2){7 g=!f&&(b.3l(e[0])>-1);7 h=!f&&(b.3l(e[1])>-1);7 i=14(d[0],10);i=(2l(i)?0:i);i=((g||h)&&i==12?0:i)+(h?12:0);7 j=14(d[1],10);j=(2l(j)?0:j);7 k=(d.E>=3?14(d[2],10):0);k=(2l(k)||!n.r(a,\'1v\')?0:k);t n.1s(a,[i,j,k])}t v},1s:q(a,b){7 c=(b!=v);p(!c){7 d=n.1u(n.r(a,\'2s\'))||D I();b=[d.1J(),d.1K(),d.1L()]}7 e=C;7 f=n.r(a,\'1Q\');1p(7 i=0;i<f.E;i++){p(e){b[i]=0}J p(f[i]>1){b[i]=F.4v(b[i]/f[i])*f[i];e=N}}t b},2k:q(a){7 b=n.r(a,\'15\');7 c=n.r(a,\'16\');7 d=(n.1M(b?a.G:((a.G+11)%12)+1)+c+n.1M(a.R)+(n.r(a,\'1v\')?c+n.1M(a.T):\'\')+(b?\'\':n.r(a,\'1d\')+n.r(a,\'Q\')[(a.G<12?0:1)]));n.1F(a,d);n.Y(a)},Y:q(a){p(a.u.4w(\':4x\')){t}7 b=a.u[0];7 c=n.r(a,\'16\');7 d=c.E+2;7 e=(a.w!=a.B?(a.w*d):(a.B*d)-c.E+n.r(a,\'1d\').E);7 f=e+(a.w!=a.B?2:n.r(a,\'Q\')[0].E);p(b.3m){b.3m(e,f)}J p(b.29){7 g=b.29();g.4y(\'3n\',e);g.4z(\'3n\',f-a.u.13().E);g.4A()}p(!b.2U&&$.o.K==b){b.1U()}},1M:q(a){t(a<10?\'0\':\'\')+a},1F:q(a,b){a.u.13(b).4B(\'4C\')},1E:q(a,b){7 c=(a.u.13()==\'\'||a.w==0);p(!c){a.w--}n.Y(a);a.1t=\'\';$.x(a.u[0],m,a);t(c&&b)},1q:q(a,b){7 c=(a.u.13()==\'\'||a.w==F.1a(1,a.O,a.B));p(!c){a.w++}n.Y(a);a.1t=\'\';$.x(a.u[0],m,a);t(c&&b)},L:q(a,b){p(a.u.13()==\'\'){b=0}7 c=n.r(a,\'1Q\');n.W(a,D I(0,0,0,a.G+(a.w==0?b*c[0]:0)+(a.w==a.B?b*12:0),a.R+(a.w==1?b*c[1]:0),a.T+(a.w==a.O?b*c[2]:0)))},W:q(a,b){b=n.1u(b);7 c=n.1s(a,b?[b.1J(),b.1K(),b.1L()]:v);b=D I(0,0,0,c[0],c[1],c[2]);7 b=n.1N(b);7 d=n.1N(n.1u(n.r(a,\'2t\')));7 e=n.1N(n.1u(n.r(a,\'2u\')));b=(d&&b<d?d:(e&&b>e?e:b));7 f=n.r(a,\'2y\');p(f){b=f.1D(a.u[0],[n.2W(a.u[0]),b,d,e])}a.G=b.1J();a.R=b.1K();a.T=b.1L();n.2k(a);$.x(a.u[0],m,a)},1u:q(h){7 i=q(a){7 b=D I();b.4D(b.25()+a*4E);t b};7 j=q(a){7 b=D I();7 c=b.1J();7 d=b.1K();7 e=b.1L();7 f=/([+-]?[0-9]+)\\s*(s|S|m|M|h|H)?/g;7 g=f.3o(a);2j(g){2b(g[2]||\'s\'){y\'s\':y\'S\':e+=14(g[1],10);z;y\'m\':y\'M\':d+=14(g[1],10);z;y\'h\':y\'H\':c+=14(g[1],10);z}g=f.3o(a)}b=D I(0,0,10,c,d,e,0);p(/^!/.4F(a)){p(b.3p()>10){b=D I(0,0,10,23,3q,3q)}J p(b.3p()<10){b=D I(0,0,10,0,0,0)}}t b};t(h?(1m h==\'2m\'?j(h):(1m h==\'4G\'?i(h):h)):v)},1N:q(a){p(!a){t v}a.4H(4I);a.4J(0);a.4K(0);t a},32:q(a,b){p(b==n.r(a,\'16\')){n.1q(a,C)}J p(b>=\'0\'&&b<=\'9\'){7 c=14(a.1t+b,10);7 d=n.r(a,\'15\');7 e=(a.w==0&&((d&&c<24)||(c>=1&&c<=12))?c+(!d&&a.G>=12?12:0):a.G);7 f=(a.w==1&&c<3r?c:a.R);7 g=(a.w==a.O&&c<3r?c:a.T);7 h=n.1s(a,[e,f,g]);n.W(a,D I(0,0,0,h[0],h[1],h[2]));a.1t=b}J p(!n.r(a,\'15\')){7 i=n.r(a,\'Q\');p((b==i[0].1b(0,1).1k()&&a.G>=12)||(b==i[1].1b(0,1).1k()&&a.G<12)){7 j=a.w;a.w=a.B;n.L(a,+1);a.w=j;n.Y(a)}}}});q 1x(a,b){$.1f(a,b);1p(7 c 3s b){p(b[c]==v){a[c]=v}}t a}$.1X.o=q(d){7 e=4L.2z.4M.4N(4O,1);p(1m d==\'2m\'&&(d==\'4P\'||d==\'25\')){t $.o[\'3t\'+d+\'1c\'].1D($.o,[n[0]].3u(e))}t n.3k(q(){7 a=n.1A.1k();p(a==\'u\'){p(1m d==\'2m\'){$.o[\'3t\'+d+\'1c\'].1D($.o,[n].3u(e))}J{7 b={};1p(1O 3s $.o.1e){7 c=n.4Q(\'4R:\'+1O);p(c){b=b||{};4S{b[1O]=4T(c)}4U(4V){b[1O]=c}}}$.o.2A(n,$.1f(b,d))}}})};$.o=D 1c()})(4W);',62,307,'|||||||var||||||||||||||||this|timeEntry|if|function|_get||return|input|null|_field|data|case|break|browser|_ampmField|false|new|length|Math|_selectedHour||Date|else|_lastInput|_adjustField||true|_secondField|_disabledInputs|ampmNames|_selectedMinute||_selectedSecond|span|bind|_setTime|unbind|_showField|_timer||||val|parseInt|show24Hours|separator|_blurredInput||target|max|substring|TimeEntry|ampmPrefix|_defaults|extend|markerClassName|options|px|msie|toLowerCase|_isDisabledTimeEntry|typeof|document|scrollLeft|for|_nextField|_getSpinnerTarget|_constrainTime|_lastChr|_determineTime|showSeconds|spinnerSize|extendRemove|left|_parseTime|nodeName|_changeSpinner|_extractTime|apply|_previousField|_setValue|abs|scrollTop|curTop|getHours|getMinutes|getSeconds|_formatNumber|_normaliseTime|attrName|regional|timeSteps|spinnerRepeat|class|mozilla|focus|_doFocus|setTimeout|fn|mousewheel|_endSpinner||_enableDisable|nextSibling|||getTime|_focussed|value|documentElement|createTextRange|keyCode|switch|opera|safari|previousSibling|_getSpinnerRegion|_actionSpinner|_repeatSpinner|_releaseSpinner|while|_showTime|isNaN|string|spinnerTexts|field|appendText|initialField|useMouseWheel|defaultTime|minTime|maxTime|spinnerImage|spinnerIncDecOnly|beforeShow|beforeSetTime|prototype|_connectTimeEntry|hasClass|background|padding|after|blur|_doBlur|click|_doClick|keydown|_doKeyDown|keypress|_doKeyPress|timeentry|paste|_doMouseWheel|_handleSpinner|mouseup|mouseout|_describeSpinner|disabled|map|_getTimeTimeEntry|clientX|srcElement|offset|ctrlKey|charCode|_handleKeyPress|one|_findPos||||||_findScroll|body|99|top|min|css|position|offsetParent|offsetLeft|offsetTop|each|indexOf|setSelectionRange|character|exec|getDate|59|60|in|_|concat|AM|PM|Now|Previous|Next|Increment|Decrement|png|500|250|hasTimeEntry|setDefaults|spinnerText|timeEntry_control|style|display|inline|block|url|no|repeat|width|height|version|bottom|wrap|timeEntry_wrap|timeEntry_append|addClass|mousedown|mousemove||_enableTimeEntry|_disableTimeEntry|push|inArray|_changeTimeEntry||_destroyTimeEntry||removeClass|unmousewheel|parent|replaceWith|removeData|_setTimeTimeEntry|object|boundingWidth|selectionStart|shiftKey|String|fromCharCode|undefined|preventDefault|title|clearTimeout|clientY|0px|parents|fixed|parentNode|split|round|is|hidden|moveStart|moveEnd|select|trigger|change|setTime|1000|test|number|setFullYear|1900|setMonth|setDate|Array|slice|call|arguments|isDisabled|getAttribute|time|try|eval|catch|err|jQuery'.split('|'),0,{}))
js/timeentry/timeEntry.png ADDED
Binary file
js/timeentry/timeEntry2.png ADDED
Binary file
js/timeentry/timeEntry3.png ADDED
Binary file
js/timeentry/timeEntry4.png ADDED
Binary file
js/timeentry/timeEntry5.png ADDED
Binary file
js/timeentry/timeEntry6.png ADDED
Binary file
dbem-it_IT.mo → langs/dbem-es_ES.mo RENAMED
Binary file
dbem-it_IT.po → langs/dbem-es_ES.po RENAMED
@@ -2,9 +2,9 @@ msgid ""
2
  msgstr ""
3
  "Project-Id-Version: events-manager\n"
4
  "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2008-08-13 16:01+0100\n"
6
  "PO-Revision-Date: \n"
7
- "Last-Translator: Davide Benini <cno@cnomania.it>\n"
8
  "Language-Team: \n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
@@ -30,7 +30,7 @@ msgstr "M"
30
 
31
  #: dbem_calendar.php:121
32
  msgid "T_Thursday_initial"
33
- msgstr "G"
34
 
35
  #: dbem_calendar.php:121
36
  msgid "F_Friday_initial"
@@ -52,45 +52,45 @@ msgstr "D"
52
  #: events-manager.php:211
53
  #: events-manager.php:222
54
  msgid "Events"
55
- msgstr "Eventi"
56
 
57
  #: dbem_widgets.php:19
58
  #: events-manager.php:46
59
  #: events-manager.php:171
60
  msgid "No events"
61
- msgstr "Nessun evento"
62
 
63
  #: dbem_widgets.php:78
64
  #: dbem_widgets.php:156
65
  msgid "Title"
66
- msgstr "Titolo"
67
 
68
  #: dbem_widgets.php:82
69
  msgid "Number of events"
70
- msgstr "Numero di eventi"
71
 
72
  #: dbem_widgets.php:86
73
  msgid "Scope of the events"
74
- msgstr "Ambito degli eventi"
75
 
76
  #: dbem_widgets.php:88
77
  #: events-manager.php:909
78
  msgid "Future events"
79
- msgstr "Eventi futuri"
80
 
81
  #: dbem_widgets.php:89
82
  #: events-manager.php:908
83
  msgid "All events"
84
- msgstr "Tutti gli eventi"
85
 
86
  #: dbem_widgets.php:90
87
  #: events-manager.php:907
88
  msgid "Past events"
89
- msgstr "Eventi passati"
90
 
91
  #: dbem_widgets.php:94
92
  msgid "Order of the events"
93
- msgstr "Ordine degli eventi"
94
 
95
  #: dbem_widgets.php:96
96
  msgid "Ascendant"
@@ -98,29 +98,29 @@ msgstr "Ascendente"
98
 
99
  #: dbem_widgets.php:97
100
  msgid "Descendant"
101
- msgstr "Discendente"
102
 
103
  #: dbem_widgets.php:101
104
  msgid "List item format"
105
- msgstr "Formato degli elementi"
106
 
107
  #: dbem_widgets.php:122
108
  msgid "calendar"
109
- msgstr "calendario "
110
 
111
  #: dbem_widgets.php:176
112
  #: dbem_widgets.php:177
113
  msgid "Events List"
114
- msgstr "Lista eventi"
115
 
116
  #: dbem_widgets.php:178
117
  #: dbem_widgets.php:179
118
  msgid "Events Calendar"
119
- msgstr "Calendario eventi"
120
 
121
  #: events-manager.php:291
122
  msgid "New event successfully inserted!"
123
- msgstr "Nuovo evento inserito!"
124
 
125
  #: events-manager.php:305
126
  msgid "Event"
@@ -128,87 +128,87 @@ msgstr "Evento"
128
 
129
  #: events-manager.php:305
130
  msgid "updated"
131
- msgstr "aggiornato"
132
 
133
  #: events-manager.php:335
134
  msgid "Insert New Event"
135
- msgstr "Inserisci un nuovo evento"
136
 
137
  #: events-manager.php:337
138
  msgid "Edit Event"
139
- msgstr "Modifica l'evento"
140
 
141
  #: events-manager.php:374
142
  msgid "Past Events"
143
- msgstr "Eventi passati"
144
 
145
  #: events-manager.php:377
146
  msgid "All Events"
147
- msgstr "Tutti gli eventi"
148
 
149
  #: events-manager.php:380
150
  msgid "Future Events"
151
- msgstr "Eventi futuri"
152
 
153
  #: events-manager.php:398
154
  msgid "Event Manager Options"
155
- msgstr "Opzioni di Events Manager"
156
 
157
  #: events-manager.php:403
158
  msgid "Default event list format"
159
- msgstr "Formato predefinito della lista eventi"
160
 
161
  #: events-manager.php:405
162
  msgid "The format of any events in a list."
163
- msgstr "Il formato di ciascun evento della lista."
164
 
165
  #: events-manager.php:406
166
- msgid "Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_VENUE</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_NOTES</code>. Use <code>#_LINKEDNAME</code> for the event name with a link to the given event page. Use #_URL to print the event URL and make your own customised links."
167
- msgstr "Inserire uno o più dei seguenti segnaposto: <code>#_NAME</code>, <code>#_VENUE</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_NOTES</code>. Utilizzare <code>#_LINKEDNAME</code> per il nome dell'evento con un link alla pagina corrispondente. Utilizzare #_URL per visualizzare l'URL dell'evento e creare link personalizzati."
168
 
169
  #: events-manager.php:407
170
  msgid "To insert date and time values, use <a href=\"http://www.php.net/manual/en/function.date.php\">PHP time format characters</a> with a # symbol before them, i.e. #m. #M, #j, etc. "
171
- msgstr "Per inserire valori di data e ora, utilizzare i <a href=\"http://www.php.net/manual/it/function.date.php\">caratteri di stringa formato PHP</a> anteponendo ad essi un #, ad esempio #m. #M, #j, etc. "
172
 
173
  #: events-manager.php:408
174
  msgid "Use HTML tags as <code>li</code>, <code>br</code>, etc."
175
- msgstr "Utilizzare liberamente tag HTML come <code>li</code>, <code>br</code>, ecc."
176
 
177
  #: events-manager.php:411
178
  msgid "Single event page title format"
179
- msgstr "Formato del titolo della pagina eventi"
180
 
181
  #: events-manager.php:414
182
  msgid "The format of a single event page title."
183
- msgstr "Il formato del titolo della pagina di un singolo evento."
184
 
185
  #: events-manager.php:415
186
  #: events-manager.php:423
187
  #: events-manager.php:492
188
  #: events-manager.php:523
189
  msgid "Follow the previous formatting instructions."
190
- msgstr "Seguire le istruzioni di formattazione precedenti."
191
 
192
  #: events-manager.php:419
193
  msgid "Default single event format"
194
- msgstr "Fomato predefinito di un singolo evento"
195
 
196
  #: events-manager.php:422
197
  msgid "The format of a single eventy page."
198
- msgstr "Il formati della pagina di un singolo evento."
199
 
200
  #: events-manager.php:424
201
  msgid "Use <code>#_MAP</code> to insert a map."
202
- msgstr "Utilizzare <code>#_MAP</code> per inserire una mappa."
203
 
204
  #: events-manager.php:432
205
  msgid "Show events page in lists?"
206
- msgstr "Mostrare la pagina degli eventi nelle liste?"
207
 
208
  #: events-manager.php:434
209
  #: events-manager.php:506
210
  msgid "Yes"
211
- msgstr ""
212
 
213
  #: events-manager.php:435
214
  #: events-manager.php:507
@@ -217,91 +217,91 @@ msgstr "No"
217
 
218
  #: events-manager.php:436
219
  msgid "Check this option if you want the events page to appear together with other pages in pages lists."
220
- msgstr "Selezionare questa opzione se si vuole che la pagina degli eventi compaia nelle liste delle pagine."
221
 
222
  #: events-manager.php:444
223
  msgid "Events page title"
224
- msgstr "Titolo della pagina degli eventi"
225
 
226
  #: events-manager.php:447
227
  msgid "The title on the multiple events page."
228
- msgstr "Il titolo della pagina che contiene più eventi."
229
 
230
  #: events-manager.php:451
231
  msgid "No events message"
232
- msgstr "Messaggio Nessun evento"
233
 
234
  #: events-manager.php:454
235
  msgid "The message displayed when no events are available."
236
- msgstr "Il messaggio visualizzato quando non ci sono eventi disponibili."
237
 
238
  #: events-manager.php:465
239
  msgid "RSS main title"
240
- msgstr "Titolo principale dell'RSS"
241
 
242
  #: events-manager.php:468
243
  msgid "The main title of your RSS events feed."
244
- msgstr "Il titolo principale del feed RSS degli eventi."
245
 
246
  #: events-manager.php:472
247
  msgid "RSS main description"
248
- msgstr "Descrizione principale dell'RSS"
249
 
250
  #: events-manager.php:475
251
  msgid "The main description of your RSS events feed."
252
- msgstr "La descrizione principale del feed RSS degli eventi."
253
 
254
  #: events-manager.php:480
255
  msgid "RSS title format"
256
- msgstr "Formato del titolo dell'RSS"
257
 
258
  #: events-manager.php:483
259
  msgid "The format of the title of each item in the events RSS feed."
260
- msgstr "Il formato del titolo di ciascun elemento nel feed RSS."
261
 
262
  #: events-manager.php:488
263
  msgid "RSS description format"
264
- msgstr "Formato della descrizione nell'RSS"
265
 
266
  #: events-manager.php:491
267
  msgid "The format of the description of each item in the events RSS feed."
268
- msgstr "Il formato della descrizione di ciascun elemento nel feed RSS."
269
 
270
  #: events-manager.php:504
271
  msgid "Enable Google Maps integration?"
272
- msgstr "Abilitare l'integrazione con Google Maps?"
273
 
274
  #: events-manager.php:508
275
  msgid "Check this option to enable Goggle Map integration."
276
- msgstr "Selezionare questa opzione per abilitare l'integrazione con Google Maps."
277
 
278
  #: events-manager.php:513
279
  msgid "Google Maps API Key"
280
- msgstr "Chiave API di Google Maps"
281
 
282
  #: events-manager.php:516
283
  msgid "To display Google Maps you need a Google Maps API key. Don't worry, it's free, you can get one"
284
- msgstr "Per visualizzare una mappa di Google Maps è necessaria una chiave API di Google Maps. Non preoccupatevi, è gratuita, è sufficiente andare su"
285
 
286
  #: events-manager.php:516
287
  msgid "here"
288
- msgstr "questa pagina"
289
 
290
  #: events-manager.php:520
291
  msgid "Map text format"
292
- msgstr "Formato del testo della mappa"
293
 
294
  #: events-manager.php:522
295
  msgid "The format the text appearing in the map cloud."
296
- msgstr "Il fomato del testo del fumetto che appare sulla mappa."
297
 
298
  #: events-manager.php:527
299
  msgid "Save Changes"
300
- msgstr "Salva le modifiche"
301
 
302
  #: events-manager.php:903
303
  msgid "New Event ..."
304
- msgstr "Nuovo evento..."
305
 
306
  #: events-manager.php:919
307
  msgid "ID"
@@ -310,98 +310,98 @@ msgstr "ID"
310
  #: events-manager.php:920
311
  #: events-manager.php:1027
312
  msgid "Name"
313
- msgstr "Nome"
314
 
315
  #: events-manager.php:921
316
  #: events-manager.php:1058
317
- msgid "Venue"
318
- msgstr "Locale"
319
 
320
  #: events-manager.php:922
321
  #: events-manager.php:1051
322
  msgid "Town"
323
- msgstr "Città"
324
 
325
  #: events-manager.php:923
326
  #: events-manager.php:1065
327
  msgid "Address"
328
- msgstr "Indirizzo"
329
 
330
  #: events-manager.php:924
331
  msgid "Date"
332
- msgstr "Data"
333
 
334
  #: events-manager.php:925
335
  msgid "Time"
336
- msgstr "Ora"
337
 
338
  #: events-manager.php:927
339
  msgid "Latitude"
340
- msgstr "Latitudine"
341
 
342
  #: events-manager.php:928
343
  msgid "Longitude"
344
- msgstr "Longitudine"
345
 
346
  #: events-manager.php:930
347
  msgid "Actions"
348
- msgstr "Azioni"
349
 
350
  #: events-manager.php:991
351
  msgid "Edit"
352
- msgstr "Modifica"
353
 
354
  #: events-manager.php:992
355
  msgid "Are you sure?"
356
- msgstr "Sei sicuro?"
357
 
358
  #: events-manager.php:992
359
  msgid "Delete"
360
- msgstr "Elimina"
361
 
362
  #: events-manager.php:1030
363
  msgid "The event name. Example: Birthday party"
364
- msgstr "Il nome dell'evento. Esempio: festa di compleanno."
365
 
366
  #: events-manager.php:1034
367
  msgid "Day and Time"
368
- msgstr "Giorno e ora."
369
 
370
  #: events-manager.php:1040
371
  msgid "The event day and time. Example: 21/11/2009 - 21:30"
372
- msgstr "Giorno e ora dell'evento. Esempio: 21/11/2009 - 21:30"
373
 
374
  #: events-manager.php:1046
375
  msgid "Map not found"
376
- msgstr "Mappa non trovata"
377
 
378
  #: events-manager.php:1054
379
  msgid "The event town. Example: Verona. If you' using the Google Map integration and want to avoid geotagging ambiguities include the country as well. Example: Verona, Italy"
380
- msgstr "La città dell'evento. Esempio: Verona. Se si utilizza Google Map e si vogliono evitare ambiguità, inserire anche lo stato. Esempio: Verona, Italy"
381
 
382
  #: events-manager.php:1061
383
- msgid "The venue where the event takes place. Example: Arena"
384
- msgstr "Il locale dove avviene l'evento. Esempio: Arena"
385
 
386
  #: events-manager.php:1068
387
- msgid "The address of the venue. Example: Via Mazzini 22"
388
- msgstr "L'indirizzo del locale. Esempio: Via Mazzini 22"
389
 
390
  #: events-manager.php:1072
391
  msgid "Notes"
392
- msgstr "Note"
393
 
394
  #: events-manager.php:1075
395
  msgid "Notes about the event"
396
- msgstr "Note sull'evento"
397
 
398
  #: events-manager.php:1080
399
  msgid "Submit Event"
400
- msgstr "Invia evento"
401
 
402
  #: events-manager.php:1345
403
  msgid "You cannot enable Google Maps integration without setting an appropriate API key."
404
- msgstr "Non è possibile abilitare l'integrazione con Google Maps senza impostare una chiave API."
405
 
406
  #~ msgid ""
407
  #~ "You are about to delete this event.\\n 'Cancel' to stop, 'OK' to delete."
2
  msgstr ""
3
  "Project-Id-Version: events-manager\n"
4
  "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2008-08-13 14:06+0100\n"
6
  "PO-Revision-Date: \n"
7
+ "Last-Translator: Ignacio Toledo <iittgg@gmail.com>\n"
8
  "Language-Team: \n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
30
 
31
  #: dbem_calendar.php:121
32
  msgid "T_Thursday_initial"
33
+ msgstr "J"
34
 
35
  #: dbem_calendar.php:121
36
  msgid "F_Friday_initial"
52
  #: events-manager.php:211
53
  #: events-manager.php:222
54
  msgid "Events"
55
+ msgstr "Eventos"
56
 
57
  #: dbem_widgets.php:19
58
  #: events-manager.php:46
59
  #: events-manager.php:171
60
  msgid "No events"
61
+ msgstr "Sin Eventos"
62
 
63
  #: dbem_widgets.php:78
64
  #: dbem_widgets.php:156
65
  msgid "Title"
66
+ msgstr "Título"
67
 
68
  #: dbem_widgets.php:82
69
  msgid "Number of events"
70
+ msgstr "Número de eventos"
71
 
72
  #: dbem_widgets.php:86
73
  msgid "Scope of the events"
74
+ msgstr "Ámbito de los eventos"
75
 
76
  #: dbem_widgets.php:88
77
  #: events-manager.php:909
78
  msgid "Future events"
79
+ msgstr "Eventos Futuros"
80
 
81
  #: dbem_widgets.php:89
82
  #: events-manager.php:908
83
  msgid "All events"
84
+ msgstr "Todos los eventos"
85
 
86
  #: dbem_widgets.php:90
87
  #: events-manager.php:907
88
  msgid "Past events"
89
+ msgstr "Eventos pasados"
90
 
91
  #: dbem_widgets.php:94
92
  msgid "Order of the events"
93
+ msgstr "Órden de los eventos"
94
 
95
  #: dbem_widgets.php:96
96
  msgid "Ascendant"
98
 
99
  #: dbem_widgets.php:97
100
  msgid "Descendant"
101
+ msgstr "Descendente"
102
 
103
  #: dbem_widgets.php:101
104
  msgid "List item format"
105
+ msgstr "Formato de lista de ítems"
106
 
107
  #: dbem_widgets.php:122
108
  msgid "calendar"
109
+ msgstr "calendario"
110
 
111
  #: dbem_widgets.php:176
112
  #: dbem_widgets.php:177
113
  msgid "Events List"
114
+ msgstr "Lista de Eventos"
115
 
116
  #: dbem_widgets.php:178
117
  #: dbem_widgets.php:179
118
  msgid "Events Calendar"
119
+ msgstr "Calendario de eventos"
120
 
121
  #: events-manager.php:291
122
  msgid "New event successfully inserted!"
123
+ msgstr "Nuevo evento ingresado correctamente!"
124
 
125
  #: events-manager.php:305
126
  msgid "Event"
128
 
129
  #: events-manager.php:305
130
  msgid "updated"
131
+ msgstr "actualizado"
132
 
133
  #: events-manager.php:335
134
  msgid "Insert New Event"
135
+ msgstr "Ingresar Nuevo Evento"
136
 
137
  #: events-manager.php:337
138
  msgid "Edit Event"
139
+ msgstr "Modificar Evento"
140
 
141
  #: events-manager.php:374
142
  msgid "Past Events"
143
+ msgstr "Eventos Pasados"
144
 
145
  #: events-manager.php:377
146
  msgid "All Events"
147
+ msgstr "Todos los Eventos"
148
 
149
  #: events-manager.php:380
150
  msgid "Future Events"
151
+ msgstr "Eventos Futuros"
152
 
153
  #: events-manager.php:398
154
  msgid "Event Manager Options"
155
+ msgstr "Opciones de Administración de Eventos"
156
 
157
  #: events-manager.php:403
158
  msgid "Default event list format"
159
+ msgstr "Formato por defecto de lista de eventos"
160
 
161
  #: events-manager.php:405
162
  msgid "The format of any events in a list."
163
+ msgstr "El formato de cualquier elemento en una lista"
164
 
165
  #: events-manager.php:406
166
+ msgid "Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_LOCATION</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_NOTES</code>. Use <code>#_LINKEDNAME</code> for the event name with a link to the given event page. Use #_URL to print the event URL and make your own customised links."
167
+ msgstr "Inserte uno o mas de estas etiquetas: <code>#_NAME</code>, <code>#_LOCATION</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_NOTES</code>. Use <code>#_LINKEDNAME</code> para mostrar el nombre de evento con un link a la página de evento correspondiente. Use #_URL para mostrar la URL del evento y hacer links personalizados."
168
 
169
  #: events-manager.php:407
170
  msgid "To insert date and time values, use <a href=\"http://www.php.net/manual/en/function.date.php\">PHP time format characters</a> with a # symbol before them, i.e. #m. #M, #j, etc. "
171
+ msgstr "Para insertar valores de fecha y hora, use <a href=\"http://www.php.net/manual/it/function.date.php\">formatos de fecha en PHP</a> con un símbolo # antepuesto, por ejemplo #m. #M, #j, etc. "
172
 
173
  #: events-manager.php:408
174
  msgid "Use HTML tags as <code>li</code>, <code>br</code>, etc."
175
+ msgstr "Use etiquetas HTML de la siguiente manera <code>li</code>, <code>br</code>, etc."
176
 
177
  #: events-manager.php:411
178
  msgid "Single event page title format"
179
+ msgstr "Formato de título de página de evento"
180
 
181
  #: events-manager.php:414
182
  msgid "The format of a single event page title."
183
+ msgstr "El formato de título de una página de evento."
184
 
185
  #: events-manager.php:415
186
  #: events-manager.php:423
187
  #: events-manager.php:492
188
  #: events-manager.php:523
189
  msgid "Follow the previous formatting instructions."
190
+ msgstr "Siga las instrucciones de formato anteriores."
191
 
192
  #: events-manager.php:419
193
  msgid "Default single event format"
194
+ msgstr "Formato por defecto de un evento"
195
 
196
  #: events-manager.php:422
197
  msgid "The format of a single eventy page."
198
+ msgstr "El formato de una página de evento."
199
 
200
  #: events-manager.php:424
201
  msgid "Use <code>#_MAP</code> to insert a map."
202
+ msgstr "Use <code>#_MAP</code> para insertar un mapa."
203
 
204
  #: events-manager.php:432
205
  msgid "Show events page in lists?"
206
+ msgstr "Mostrar eventos en los listados de páginas"
207
 
208
  #: events-manager.php:434
209
  #: events-manager.php:506
210
  msgid "Yes"
211
+ msgstr "Si"
212
 
213
  #: events-manager.php:435
214
  #: events-manager.php:507
217
 
218
  #: events-manager.php:436
219
  msgid "Check this option if you want the events page to appear together with other pages in pages lists."
220
+ msgstr "Chequee esta opción si desea que la página de eventos aparezca junto a otras páginas en los listados de página."
221
 
222
  #: events-manager.php:444
223
  msgid "Events page title"
224
+ msgstr "Título de página de eventos"
225
 
226
  #: events-manager.php:447
227
  msgid "The title on the multiple events page."
228
+ msgstr "El título en página con múltiples eventos."
229
 
230
  #: events-manager.php:451
231
  msgid "No events message"
232
+ msgstr "Mensaje sin eventos"
233
 
234
  #: events-manager.php:454
235
  msgid "The message displayed when no events are available."
236
+ msgstr "El mensaje a mostrar cuando no hay eventos disponibles."
237
 
238
  #: events-manager.php:465
239
  msgid "RSS main title"
240
+ msgstr "Título principal del RSS"
241
 
242
  #: events-manager.php:468
243
  msgid "The main title of your RSS events feed."
244
+ msgstr "El título principal de su pulicación RSS de eventos."
245
 
246
  #: events-manager.php:472
247
  msgid "RSS main description"
248
+ msgstr "Descripción principal de la publicación por RSS"
249
 
250
  #: events-manager.php:475
251
  msgid "The main description of your RSS events feed."
252
+ msgstr "La descripción principal de su publicación RSS de eventos."
253
 
254
  #: events-manager.php:480
255
  msgid "RSS title format"
256
+ msgstr "Formato de título de su publicación RSS."
257
 
258
  #: events-manager.php:483
259
  msgid "The format of the title of each item in the events RSS feed."
260
+ msgstr "El formato de título de cada ítem en la publicación RSS."
261
 
262
  #: events-manager.php:488
263
  msgid "RSS description format"
264
+ msgstr "Formato de la descripción RSS"
265
 
266
  #: events-manager.php:491
267
  msgid "The format of the description of each item in the events RSS feed."
268
+ msgstr "El formato de la descripción de cada ítem en la publicación RSS de eventos."
269
 
270
  #: events-manager.php:504
271
  msgid "Enable Google Maps integration?"
272
+ msgstr "¿Activar integración con Google Maps?"
273
 
274
  #: events-manager.php:508
275
  msgid "Check this option to enable Goggle Map integration."
276
+ msgstr "Seleccione esta opción para activar la integración con Google Maps."
277
 
278
  #: events-manager.php:513
279
  msgid "Google Maps API Key"
280
+ msgstr "Clave de Google Maps."
281
 
282
  #: events-manager.php:516
283
  msgid "To display Google Maps you need a Google Maps API key. Don't worry, it's free, you can get one"
284
+ msgstr "Para poder visualizar los Google Maps necesita un Key. No se preocupe, es gratuito y puede conseguir una"
285
 
286
  #: events-manager.php:516
287
  msgid "here"
288
+ msgstr "aquí"
289
 
290
  #: events-manager.php:520
291
  msgid "Map text format"
292
+ msgstr "Formato del texto del mapa"
293
 
294
  #: events-manager.php:522
295
  msgid "The format the text appearing in the map cloud."
296
+ msgstr "El formato del texto que aparece en la nube del mapa."
297
 
298
  #: events-manager.php:527
299
  msgid "Save Changes"
300
+ msgstr "Guardar los cambios"
301
 
302
  #: events-manager.php:903
303
  msgid "New Event ..."
304
+ msgstr "Nuevo Evento ..."
305
 
306
  #: events-manager.php:919
307
  msgid "ID"
310
  #: events-manager.php:920
311
  #: events-manager.php:1027
312
  msgid "Name"
313
+ msgstr "Nombre"
314
 
315
  #: events-manager.php:921
316
  #: events-manager.php:1058
317
+ msgid "Location"
318
+ msgstr "Lugar"
319
 
320
  #: events-manager.php:922
321
  #: events-manager.php:1051
322
  msgid "Town"
323
+ msgstr "Ciudad"
324
 
325
  #: events-manager.php:923
326
  #: events-manager.php:1065
327
  msgid "Address"
328
+ msgstr "Dirección"
329
 
330
  #: events-manager.php:924
331
  msgid "Date"
332
+ msgstr "Fecha"
333
 
334
  #: events-manager.php:925
335
  msgid "Time"
336
+ msgstr "Hora"
337
 
338
  #: events-manager.php:927
339
  msgid "Latitude"
340
+ msgstr "Latitud"
341
 
342
  #: events-manager.php:928
343
  msgid "Longitude"
344
+ msgstr "Longitud"
345
 
346
  #: events-manager.php:930
347
  msgid "Actions"
348
+ msgstr "Acciones"
349
 
350
  #: events-manager.php:991
351
  msgid "Edit"
352
+ msgstr "Editar"
353
 
354
  #: events-manager.php:992
355
  msgid "Are you sure?"
356
+ msgstr "¿Está Seguro?"
357
 
358
  #: events-manager.php:992
359
  msgid "Delete"
360
+ msgstr "Eliminar"
361
 
362
  #: events-manager.php:1030
363
  msgid "The event name. Example: Birthday party"
364
+ msgstr "El nombre del evento. Ejemplo: Fiesta de Cumpleaños"
365
 
366
  #: events-manager.php:1034
367
  msgid "Day and Time"
368
+ msgstr "Fecha y Hora"
369
 
370
  #: events-manager.php:1040
371
  msgid "The event day and time. Example: 21/11/2009 - 21:30"
372
+ msgstr "Fecha y hora del evento. Ejemplo: 21/11/2009 - 21:30"
373
 
374
  #: events-manager.php:1046
375
  msgid "Map not found"
376
+ msgstr "Mapa no encontrado"
377
 
378
  #: events-manager.php:1054
379
  msgid "The event town. Example: Verona. If you' using the Google Map integration and want to avoid geotagging ambiguities include the country as well. Example: Verona, Italy"
380
+ msgstr "La ciudad del evento. Por ejemplo: Verona. Si esta usando integración con Google Maps y quiere evitar ambiguedades al geolocalizar incluya también el país. Ejemplo: Verona, Italia"
381
 
382
  #: events-manager.php:1061
383
+ msgid "The location where the event takes place. Example: Arena"
384
+ msgstr "El establecimiento donde toma lugar el evento. Ejemplo: Arena"
385
 
386
  #: events-manager.php:1068
387
+ msgid "The address of the location. Example: Via Mazzini 22"
388
+ msgstr "La dirección del establecimiento. Ejemplo: Calle Mazzini, 22"
389
 
390
  #: events-manager.php:1072
391
  msgid "Notes"
392
+ msgstr "Notas"
393
 
394
  #: events-manager.php:1075
395
  msgid "Notes about the event"
396
+ msgstr "Notas sobre el evento"
397
 
398
  #: events-manager.php:1080
399
  msgid "Submit Event"
400
+ msgstr "Guardar Evento"
401
 
402
  #: events-manager.php:1345
403
  msgid "You cannot enable Google Maps integration without setting an appropriate API key."
404
+ msgstr "No puede activar la integración con Google Maps sin establecer una clave adecuada."
405
 
406
  #~ msgid ""
407
  #~ "You are about to delete this event.\\n 'Cancel' to stop, 'OK' to delete."
langs/dbem-it_IT.mo ADDED
Binary file
langs/dbem-it_IT.po ADDED
@@ -0,0 +1,1132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: events-manager\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2009-03-03 19:23+0100\n"
6
+ "PO-Revision-Date: \n"
7
+ "Last-Translator: Davide Benini <cno@cnomania.it>\n"
8
+ "Language-Team: \n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Poedit-Language: Italian\n"
13
+ "X-Poedit-Country: ITALY\n"
14
+ "X-Poedit-SourceCharset: utf-8\n"
15
+ "X-Poedit-Basepath: /Users/davidebenini/Sites/testblog/wp-content/plugins/events-manager/\n"
16
+ "X-Poedit-KeywordsList: _e;__\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: dbem-recurrence.php:224
20
+ msgid "Monday"
21
+ msgstr "Lunedì"
22
+
23
+ #: dbem-recurrence.php:224
24
+ msgid "Tuesday"
25
+ msgstr "Martedì"
26
+
27
+ #: dbem-recurrence.php:224
28
+ msgid "Wednesday"
29
+ msgstr "Mercoledì"
30
+
31
+ #: dbem-recurrence.php:224
32
+ msgid "Thursday"
33
+ msgstr "Giovedì"
34
+
35
+ #: dbem-recurrence.php:224
36
+ msgid "Friday"
37
+ msgstr "Venerdì"
38
+
39
+ #: dbem-recurrence.php:224
40
+ msgid "Saturday"
41
+ msgstr "Sabato"
42
+
43
+ #: dbem-recurrence.php:224
44
+ msgid "Sunday"
45
+ msgstr "Domenica"
46
+
47
+ #: dbem-recurrence.php:225
48
+ #, php-format
49
+ msgid "the first %s of the month"
50
+ msgstr "il primo %s del mese"
51
+
52
+ #: dbem-recurrence.php:225
53
+ #, php-format
54
+ msgid "the second %s of the month"
55
+ msgstr "il secondo % del mese"
56
+
57
+ #: dbem-recurrence.php:225
58
+ #, php-format
59
+ msgid "the third %s of the month"
60
+ msgstr "il terso %s del mese"
61
+
62
+ #: dbem-recurrence.php:225
63
+ #, php-format
64
+ msgid "the fourth %s of the month"
65
+ msgstr "il quarto %s del mese"
66
+
67
+ #: dbem-recurrence.php:225
68
+ #, php-format
69
+ msgid "the last %s of the month"
70
+ msgstr "l'ultimo %s del mese"
71
+
72
+ #: dbem-recurrence.php:226
73
+ #, php-format
74
+ msgid "From %1$s to %2$s"
75
+ msgstr "Dal %1$s al %2$s"
76
+
77
+ #: dbem-recurrence.php:229
78
+ msgid "everyday"
79
+ msgstr "ogni giorno"
80
+
81
+ #: dbem-recurrence.php:231
82
+ #, php-format
83
+ msgid "every %s days"
84
+ msgstr "ogni %s giorni"
85
+
86
+ #: dbem-recurrence.php:241
87
+ #, php-format
88
+ msgid "every %s weeks"
89
+ msgstr "ogni %s settimane"
90
+
91
+ #: dbem-recurrence.php:252
92
+ #, php-format
93
+ msgid "every %s months"
94
+ msgstr "ogni %s mesi"
95
+
96
+ #: dbem_events.php:6
97
+ #: dbem_events.php:175
98
+ msgid "Insert New Event"
99
+ msgstr "Inserisci un nuovo evento"
100
+
101
+ #: dbem_events.php:127
102
+ msgid "New recurrent event inserted!"
103
+ msgstr "Nuovo evento ricorrente inserito!"
104
+
105
+ #: dbem_events.php:131
106
+ msgid "New event successfully inserted!"
107
+ msgstr "Nuovo evento inserito!"
108
+
109
+ #: dbem_events.php:140
110
+ msgid "Recurrence updated!"
111
+ msgstr "Ricorrenza aggiornata!"
112
+
113
+ #: dbem_events.php:142
114
+ msgid "Something went wrong with the recurrence update..."
115
+ msgstr "Caspita, si è verificato un problema durante l'aggiornamento della ricorrenza..."
116
+
117
+ #: dbem_events.php:150
118
+ msgid "updated"
119
+ msgstr "aggiornato"
120
+
121
+ #: dbem_events.php:167
122
+ msgid "Ach, there's a problem here:"
123
+ msgstr "Houston, abbiamo un problema:"
124
+
125
+ #: dbem_events.php:178
126
+ msgid "Edit Event"
127
+ msgstr "Modifica l'evento"
128
+
129
+ #: dbem_events.php:193
130
+ #: dbem_events.php:929
131
+ #: dbem_events.php:1106
132
+ msgid "Reschedule"
133
+ msgstr "Riprogramma"
134
+
135
+ #: dbem_events.php:210
136
+ msgid "Past Events"
137
+ msgstr "Eventi passati"
138
+
139
+ #: dbem_events.php:213
140
+ msgid "All Events"
141
+ msgstr "Tutti gli eventi"
142
+
143
+ #: dbem_events.php:216
144
+ msgid "Future Events"
145
+ msgstr "Eventi futuri"
146
+
147
+ #: dbem_events.php:239
148
+ msgid "Event Manager Options"
149
+ msgstr "Opzioni di Events Manager"
150
+
151
+ #: dbem_events.php:242
152
+ msgid "Events format"
153
+ msgstr "Formato eventi"
154
+
155
+ #: dbem_events.php:245
156
+ msgid "Default event list format"
157
+ msgstr "Formato predefinito della lista eventi"
158
+
159
+ #: dbem_events.php:245
160
+ msgid "The format of any events in a list.<br/>Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_LOCATION</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_NOTES</code>.<br/> Use <code>#_LINKEDNAME</code> for the event name with a link to the given event page.<br/> Use <code>#_EVENTPAGEURL</code> to print the event page URL and make your own customised links.<br/> Use <code>#_LOCATIONPAGEURL</code> to print the location page URL and make your own customised links.<br/>To insert date and time values, use <a href=\"http://www.php.net/manual/en/function.date.php\">PHP time format characters</a> with a <code>#</code> symbol before them, i.e. <code>#m</code>, <code>#M</code>, <code>#j</code>, etc.<br/> For the end time, put <code>#@</code> in front of the character, ie. <code>#@h</code>, <code>#@i</code>, etc.<br/> Feel free to use HTML tags as <code>li</code>, <code>br</code> and so on."
161
+ msgstr "Il formato degli eventi in una lista.<br/>Inserire uno o più dei seguenti segnaposto: <code>#_NAME</code>, <code>#_LOCATION</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_NOTES</code>.<br/> Utilizzare <code>#_LINKEDNAME</code> per visualizzare il nome dell'evento con un link alla pagina relativa.<br/> Utilizzare <code>#_EVENTPAGEURL</code> per ottenere l'URL della pagina e creare da un proprio link personalizzzato.<br/> Utilizzare <code>#_LOCATIONPAGEURL</code> per ottenere l'URL della pagina del luogo e creare un link personalizzato.<br/>Per inserire valori temporali, utilizzare i <a href=\"http://www.php.net/manual/it/function.date.php\">caratteri dells stringa formato PHP</a> anteponendo il carattere <code>#</code> , ad esempio <code>#m</code>, <code>#M</code>, <code>#j</code>, etc.<br/> Per l'ora di fine dell'evento anteporre il carattere <code>#@</code>, ad esempio <code>#@h</code>, <code>#@i</code>, etc.<br/> Utilizzare liberamente i tag HTML come <code>li</code>, <code>br</code> e così via."
162
+
163
+ #: dbem_events.php:246
164
+ msgid "Single event page title format"
165
+ msgstr "Formato del titolo della pagina Evento singolo"
166
+
167
+ #: dbem_events.php:246
168
+ msgid "The format of a single event page title. Follow the previous formatting instructions."
169
+ msgstr "Il formato della pagina di un singolo evento. Seguire le istruzioni di formattazione precedenti."
170
+
171
+ #: dbem_events.php:247
172
+ msgid "Default single event format"
173
+ msgstr "Fomato predefinito di un singolo evento"
174
+
175
+ #: dbem_events.php:247
176
+ msgid "The format of a single event page.<br/>Follow the previous formatting instructions. <br/>Use <code>#_MAP</code> to insert a map.<br/>Use <code>#_CONTACTNAME</code>, <code>#_CONTACTEMAIL</code>, <code>#_CONTACTPHONE</code> to insert respectively the name, e-mail address and phone number of the designated contact person. <br/>Use <code>#_ADDBOOKINGFORM</code> to insert a form to allow the user to respond to your events reserving one or more places (RSVP).<br/> Use <code>#_REMOVEBOOKINGFORM</code> to insert a form where users, inserting their name and e-mail address, can remove their bookings."
177
+ msgstr "Il formato delle pagine Evento singolo.<br/>Seguire le istruzioni di formattazione precedenti. <br/>Utilizzare <code>#_MAP</code> per inserire una mappa.<br/>Utilizzare <code>#_CONTACTNAME</code>, <code>#_CONTACTEMAIL</code>, <code>#_CONTACTPHONE</code> per inserire rispettivamente nome, e-mail e telefono del responsabile dell'evento. <br/>Utilizzare <code>#_ADDBOOKINGFORM</code> per inserire un modulo di registrazione per l'evento (RSVP).<br/> Utilizzare <code>#_REMOVEBOOKINGFORM</code> per inserire un modulo per cancellare le registrazioni."
178
+
179
+ #: dbem_events.php:248
180
+ msgid "Show events page in lists?"
181
+ msgstr "Mostrare la pagina degli eventi nelle liste?"
182
+
183
+ #: dbem_events.php:248
184
+ msgid "Check this option if you want the events page to appear together with other pages in pages lists."
185
+ msgstr "Selezionare questa opzione se si vuole che la pagina eventi appaia"
186
+
187
+ #: dbem_events.php:249
188
+ msgid "Events page title"
189
+ msgstr "Titolo della pagina degli eventi"
190
+
191
+ #: dbem_events.php:249
192
+ msgid "The title on the multiple events page."
193
+ msgstr "Il titolo della pagina che contiene più eventi."
194
+
195
+ #: dbem_events.php:250
196
+ msgid "No events message"
197
+ msgstr "Messaggio Nessun evento"
198
+
199
+ #: dbem_events.php:250
200
+ msgid "The message displayed when no events are available."
201
+ msgstr "Il messaggio visualizzato quando non ci sono eventi disponibili."
202
+
203
+ #: dbem_events.php:251
204
+ msgid "Map text format"
205
+ msgstr "Formato del testo della mappa"
206
+
207
+ #: dbem_events.php:251
208
+ msgid "The format the text appearing in the event page map cloud.<br/>Follow the previous formatting instructions."
209
+ msgstr "Il formato della testo che appare nel fumetto della mappa della pagina Evento singolo. Seguire le istruzioni di formattazione precedenti."
210
+
211
+ #: dbem_events.php:255
212
+ msgid "Locations format"
213
+ msgstr "Formato del luogo"
214
+
215
+ #: dbem_events.php:257
216
+ msgid "Single location page title format"
217
+ msgstr "Formato del titolo della pagina Luogo singolo"
218
+
219
+ #: dbem_events.php:257
220
+ msgid "The format of a single location page title.<br/>Follow the previous formatting instructions."
221
+ msgstr "Il formato del titolo della pagina di un singolo evento.<br/>Seguire le istruzioni di formattazione precedenti."
222
+
223
+ #: dbem_events.php:258
224
+ msgid "Default single location page format"
225
+ msgstr "Formato predefinito della pagina Luogo singolo"
226
+
227
+ #: dbem_events.php:258
228
+ msgid "The format of a single location page.<br/>Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_DESCRIPTION</code>.<br/> Use <code>#_MAP</code> to display a map of the event location, and <code>#_IMAGE</code> to display an image of the location.<br/> Use <code>#_NEXTEVENTS</code> to insert a list of the upcoming events, <code>#_PASTEVENTS</code> for a list of past events, <code>#_ALLEVENTS</code> for a list of all events taking place in this location."
229
+ msgstr "Il formato di una pagina Luogo singolo.<br/>Inserire uno o più dei seguenti segnaposto: <code>#_NAME</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_DESCRIPTION</code>.<br/> Utilizzare <code>#_MAP</code> per visualizzare una mappa del luogo dell'evento, e <code>#_IMAGE</code> per visualizzare un'immagine del luogo.<br/> Utilizzare <code>#_NEXTEVENTS</code> per inserire un elenco degli eventi futuri, <code>#_PASTEVENTS</code> per un elenco degli eventi passati, <code>#_ALLEVENTS</code> per un elenco di tutti gli eventi che si tengono in un luogo."
230
+
231
+ #: dbem_events.php:259
232
+ msgid "Default location baloon format"
233
+ msgstr "Fomato predefinito del fumetto predefinito di un luogo"
234
+
235
+ #: dbem_events.php:259
236
+ msgid "The format of of the text appearing in the baloon describing the location in the map.<br/>Insert one or more of the following placeholders: <code>#_NAME</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_DESCRIPTION</code> or <code>#_IMAGE</code>."
237
+ msgstr "Il formato del testo che appare nel fumetto che descrive l'ubicazione sulla mappa.<br/>Inserire uno o più dei seguenti segnaposto: <code>#_NAME</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, <code>#_DESCRIPTION</code> o <code>#_IMAGE</code>."
238
+
239
+ #: dbem_events.php:260
240
+ msgid "Default location event list format"
241
+ msgstr "Formato predefinito della lista eventi del luogo"
242
+
243
+ #: dbem_events.php:260
244
+ msgid "The format of the events the list inserted in the location page through the <code>#_NEXTEVENTS</code>, <code>#_PASTEVENTS</code> and <code>#_ALLEVENTS</code> element. <br/> Follow the events formatting instructions"
245
+ msgstr "Il formato dell'evento nell'elenco inserito nella pagina del luogo con gli elementi <code>#_NEXTEVENTS</code>, <code>#_PASTEVENTS</code> e <code>#_ALLEVENTS</code>. <br/> Seguire le istruzioni di formattazione precedenti."
246
+
247
+ #: dbem_events.php:261
248
+ msgid "Default no events message"
249
+ msgstr "Messaggio Nessun evento "
250
+
251
+ #: dbem_events.php:261
252
+ msgid "The message to be displayed in the list generated by <code>#_NEXTEVENTS</code>, <code>#_PASTEVENTS</code> and <code>#_ALLEVENTS</code> when no events are available."
253
+ msgstr "Il messaggio da visualizzare nell'elenco generato da <code>#_NEXTEVENTS</code>, <code>#_PASTEVENTS</code> e <code>#_ALLEVENTS</code> quando non sono disponibili eventi."
254
+
255
+ #: dbem_events.php:266
256
+ msgid "RSS feed format"
257
+ msgstr "Formato del feed RSS"
258
+
259
+ #: dbem_events.php:269
260
+ msgid "RSS main title"
261
+ msgstr "Titolo principale dell'RSS"
262
+
263
+ #: dbem_events.php:269
264
+ msgid "The main title of your RSS events feed."
265
+ msgstr "Il titolo principale del feed RSS degli eventi."
266
+
267
+ #: dbem_events.php:270
268
+ msgid "RSS main description"
269
+ msgstr "Descrizione principale dell'RSS"
270
+
271
+ #: dbem_events.php:270
272
+ msgid "The main description of your RSS events feed."
273
+ msgstr "La descrizione principale del feed RSS degli eventi."
274
+
275
+ #: dbem_events.php:271
276
+ msgid "RSS title format"
277
+ msgstr "Formato del titolo dell'RSS"
278
+
279
+ #: dbem_events.php:271
280
+ msgid "The format of the title of each item in the events RSS feed."
281
+ msgstr "Il formato del titolo di ciascun elemento nel feed RSS."
282
+
283
+ #: dbem_events.php:272
284
+ msgid "RSS description format"
285
+ msgstr "Formato della descrizione nell'RSS"
286
+
287
+ #: dbem_events.php:272
288
+ msgid "The format of the description of each item in the events RSS feed. Follow the previous formatting instructions."
289
+ msgstr "Il formato della descrizione di ogni singolo elemento nel feed RSS. Seguire le istruzioni di formattazione precedenti."
290
+
291
+ #: dbem_events.php:275
292
+ msgid "Maps and geotagging"
293
+ msgstr "Mappe e geotagging"
294
+
295
+ #: dbem_events.php:280
296
+ msgid "Enable Google Maps integration?"
297
+ msgstr "Abilitare l'integrazione con Google Maps?"
298
+
299
+ #: dbem_events.php:282
300
+ #: dbem_UI_helpers.php:68
301
+ msgid "Yes"
302
+ msgstr "Sì"
303
+
304
+ #: dbem_events.php:283
305
+ #: dbem_UI_helpers.php:69
306
+ msgid "No"
307
+ msgstr "No"
308
+
309
+ #: dbem_events.php:284
310
+ msgid "Check this option to enable Goggle Map integration."
311
+ msgstr "Selezionare questa opzione per abilitare l'integrazione con Google Maps."
312
+
313
+ #: dbem_events.php:288
314
+ msgid "Google Maps API Key"
315
+ msgstr "Chiave API di Google Maps"
316
+
317
+ #: dbem_events.php:288
318
+ #, php-format
319
+ msgid "To display Google Maps you need a Google Maps API key. Don't worry, it's free, you can get one <a href='%s'>here</a>."
320
+ msgstr "Per visualizzare una mappa di Google Maps è necessaria una chiave API di Google Maps. Non preoccupatevi, è gratuita, è sufficiente andare su <a href='%s'>questa pagina</a>."
321
+
322
+ #: dbem_events.php:292
323
+ msgid "RSVP and bookings"
324
+ msgstr "RSVP e prenotazioni"
325
+
326
+ #: dbem_events.php:295
327
+ msgid "Default contact person"
328
+ msgstr "Responsabile degli eventi predefinito"
329
+
330
+ #: dbem_events.php:295
331
+ msgid "Select the default contact person. This user will be employed whenever a contact person is not explicitly specified for an event"
332
+ msgstr "Selezionare il respondsponsabile predefinito degli eventi. Quando non verrà indicato esplicitamente un reponsabile per un evento, verrà utilizzato questo utente."
333
+
334
+ #: dbem_events.php:296
335
+ msgid "Enable the RSVP e-mail notifications?"
336
+ msgstr "Abilitare le notifiche e-mail RSVP?"
337
+
338
+ #: dbem_events.php:296
339
+ msgid "Check this option if you want to receive an email when someone books places for your events."
340
+ msgstr "Selezionare questa opzione se si vuole ricevere un'e-mail quando qualcuno prenota posti per un'evento."
341
+
342
+ #: dbem_events.php:297
343
+ #: dbem_events.php:298
344
+ msgid "Contact person email format"
345
+ msgstr "Formato dell'e-mail inviata al responsabile"
346
+
347
+ #: dbem_events.php:297
348
+ msgid "The format or the email which will be sent to the contact person. Follow the events formatting instructions. <br/>Use <code>#_RESPNAME</code>, <code>#_RESPEMAIL</code> and <code>#_RESPPHONE</code> to display respectively the name, e-mail, address and phone of the respondent.<br/>Use <code>#_SPACES</code> to display the number of spaces reserved by the respondent.<br/> Use <code>#_BOOKEDSEATS</code> and <code>#_AVAILABLESEATS</code> to display respectively the number of booked and available seats."
349
+ msgstr "Il formato del'email cje verrà inviata al reponsabile.<br/>Seguire le istruzioni di formattazione precedenti. <br/>Utilizzare <code>#_RESPNAME</code>, <code>#_RESPEMAIL</code> e <code>#_RESPPHONE</code> per inserire rispettivamente il nome, l'email e l'indirizzo dell'utente che ha prenotato.<br/>Utilizzare <code>#_SPACES</code> per inserire il numero di posti prenotati dall'utente.<br/> Utilizzare <code>#_BOOKEDSEATS</code> e <code>#_AVAILABLESEATS</code> per inserire il numero di posti prenotati e liberi."
350
+
351
+ #: dbem_events.php:298
352
+ msgid "The format or the email which will be sent to reposdent. Follow the events formatting instructions. <br/>Use <code>#_RESPNAME</code> to display the name of the respondent.<br/>Use <code>#_CONTACTNAME</code> and <code>#_CONTACTMAIL</code> a to display respectively the name and e-mail of the contact person.<br/>Use <code>#_SPACES</code> to display the number of spaces reserved by the respondent."
353
+ msgstr "Il formato dell'e-mail che verrà inviata all'utente che prenota. Seguire le istruzioni di formattazione precedenti. <br/>Utilizzare <code>#_RESPNAME</code> per visualizzare il nome dell'utente che prenota.<br/>Utilizzare <code>#_CONTACTNAME</code> e <code>#_CONTACTMAIL</code> per inserire rispettivamente il nome e l'e-mail del responsabile dell'evento.<br/>Utilizzare <code>#_SPACES</code> per visualizzare informazioni relative ai posti prenotato."
354
+
355
+ #: dbem_events.php:299
356
+ msgid "Notification sender name"
357
+ msgstr "Nome del mittente della notifica"
358
+
359
+ #: dbem_events.php:299
360
+ msgid "Insert the display name of the notification sender."
361
+ msgstr "Inserire il nome del mittente che verrà visualizzato."
362
+
363
+ #: dbem_events.php:300
364
+ msgid "Notification sender address"
365
+ msgstr "Indirizzo del mittente della notifica"
366
+
367
+ #: dbem_events.php:300
368
+ msgid "Insert the address of the notification sender. It must corresponds with your gmail account user"
369
+ msgstr "Inserire l'indirizzo del mittente della notifica. Se si utilizza GMail, deve corrispondere al nome utente Gmail"
370
+
371
+ #: dbem_events.php:301
372
+ msgid "Default notification receiver address"
373
+ msgstr "Indirizzo di ricezione delle notifiche predefinito"
374
+
375
+ #: dbem_events.php:301
376
+ msgid "Insert the address of the receiver of your notifications"
377
+ msgstr "Inserire l'indirizzo del destinatario delle notifiche"
378
+
379
+ #: dbem_events.php:302
380
+ msgid "The port through which you e-mail notifications will be sent. Make sure the firewall doesn't block this port"
381
+ msgstr "La porta utilizzata per inviare le notifiche via e-mail. Accertarsi che la porta non sia bloccata da un firewall"
382
+
383
+ #: dbem_events.php:303
384
+ msgid "Mail sending method"
385
+ msgstr "Metodo di invio delle e-mail"
386
+
387
+ #: dbem_events.php:303
388
+ msgid "PHP mail function"
389
+ msgstr "Funzione mail di PHP"
390
+
391
+ #: dbem_events.php:303
392
+ msgid "Select the method to send email notification."
393
+ msgstr "Selezionare il metoto per inviare le notifiche e-mail"
394
+
395
+ #: dbem_events.php:304
396
+ msgid "Use SMTP authentication?"
397
+ msgstr "Utilizzare l'autenticazione SMTP?"
398
+
399
+ #: dbem_events.php:304
400
+ msgid "SMTP authenticatio is often needed. If you use GMail, make sure to set this parameter to Yes"
401
+ msgstr "Spesso è necessario utilizzare l'autenticazione SMTP. Se si utilizza GMail, impostare questo parametro su Sì."
402
+
403
+ #: dbem_events.php:305
404
+ msgid "The SMTP host. Usually it corresponds to 'localhost'. If you use GMail, set this value to 'ssl://smtp.gmail.com:465'."
405
+ msgstr "L'host SMTP. Generalmente corrisponde a 'localhost'. Se si utilizza GMail, impostare questo valore su 'ssl://smtp.gmail.com:465'."
406
+
407
+ #: dbem_events.php:306
408
+ msgid "SMTP username"
409
+ msgstr "Nome utente SMTP"
410
+
411
+ #: dbem_events.php:306
412
+ msgid "Insert the username to be used to access your SMTP server."
413
+ msgstr "Inserire il nome utente da utilizzare per l'accesso al server SMTP."
414
+
415
+ #: dbem_events.php:307
416
+ msgid "SMTP password"
417
+ msgstr "PAssword SMTP"
418
+
419
+ #: dbem_events.php:307
420
+ msgid "Insert the password to be used to access your SMTP server"
421
+ msgstr "Inserire la password da utilizzare per accedere al proprio server SMTP."
422
+
423
+ #: dbem_events.php:313
424
+ msgid "Images size"
425
+ msgstr "Dimensioni immagini"
426
+
427
+ #: dbem_events.php:315
428
+ msgid "Maximum width (px)"
429
+ msgstr "Larghezza massima (px)"
430
+
431
+ #: dbem_events.php:315
432
+ msgid "The maximum allowed width for images uploades"
433
+ msgstr "La larghezza massima consentita per le immagini caricate"
434
+
435
+ #: dbem_events.php:316
436
+ msgid "Maximum height (px)"
437
+ msgstr "Altezza massimaa (px)"
438
+
439
+ #: dbem_events.php:316
440
+ msgid "The maximum allowed width for images uploaded, in pixels"
441
+ msgstr "La larghezza massima delle immagini caricate, in pixel"
442
+
443
+ #: dbem_events.php:317
444
+ msgid "Maximum size (bytes)"
445
+ msgstr "Dimensioni massime (byte)"
446
+
447
+ #: dbem_events.php:317
448
+ msgid "The maximum allowed size for images uploaded, in pixels"
449
+ msgstr "La dimensione massima consentita per le immmagini, in pixel"
450
+
451
+ #: dbem_events.php:324
452
+ msgid "Save Changes"
453
+ msgstr "Salva le modifiche"
454
+
455
+ #: dbem_events.php:781
456
+ #, php-format
457
+ msgid ""
458
+ "<p>Hey, <strong>%s</strong>, welcome to <strong>Events Manager</strong>! We hope you like around here.</p> \n"
459
+ "\t<p>Now it's time to insert events lists through <a href='%s' title='Widgets page'>widgets</a>, <a href='%s' title='Template tags documentation'>template tags</a> or <a href='%s' title='Shortcodes documentation'>shortcodes</a>.</p>\n"
460
+ "\t<p>By the way, have you taken a look at the <a href='%s' title='Change settings'>Settings page</a>? That's where you customize the way events and locations are displayed.</p>\n"
461
+ "\t<p>What? Tired of seeing this advice? I hear you, <a href='%s' title='Don't show this advice again'>click here</a> and you won't see this again!</p>"
462
+ msgstr ""
463
+ "<p>Hey, <strong>%s</strong>, <strong>Events Manager</strong> ti dà il benvenuto a bordo! </p> \n"
464
+ "\t<p>Ora è il momento di inserire un elenco degli eventi con <a href='%s' title='Pagina widget'>widgets</a>, <a href='%s' title='Template tag, documentazione'>template tag</a> o <a href='%s' title='Shortcode, documentaizone'>shortcode</a>.</p>\n"
465
+ "\t<p>Dimenticavo, hai dato un'occhiata alla <a href='%s' title='Change settings'>pagina delle Impostazioni</a>? Troverai un sacco di parametri per ottimizzare la visualizzazione degli eventi.</p>\n"
466
+ "\t<p>Cosa? Stufo di questa pappardella? Capisco, <a href='%s' title='Non mostrare più questo avvico'>fai clic qui</a> per non vedere più questo avviso.</p>"
467
+
468
+ #: dbem_events.php:824
469
+ msgid "New Event ..."
470
+ msgstr "Nuovo evento..."
471
+
472
+ #: dbem_events.php:828
473
+ #: dbem_events.php:833
474
+ #: dbem_widgets.php:90
475
+ msgid "Past events"
476
+ msgstr "Eventi passati"
477
+
478
+ #: dbem_events.php:829
479
+ #: dbem_events.php:834
480
+ #: dbem_widgets.php:89
481
+ msgid "All events"
482
+ msgstr "Tutti gli eventi"
483
+
484
+ #: dbem_events.php:830
485
+ #: dbem_events.php:835
486
+ #: dbem_widgets.php:88
487
+ msgid "Future events"
488
+ msgstr "Eventi futuri"
489
+
490
+ #: dbem_events.php:842
491
+ msgid "Total"
492
+ msgstr "Totali"
493
+
494
+ #: dbem_events.php:849
495
+ msgid "Bulk Actions"
496
+ msgstr "Azioni "
497
+
498
+ #: dbem_events.php:850
499
+ msgid "Delete selected"
500
+ msgstr "Elimina selezionati"
501
+
502
+ #: dbem_events.php:865
503
+ msgid "Filter"
504
+ msgstr "Filtro"
505
+
506
+ #: dbem_events.php:880
507
+ #: dbem_events.php:1156
508
+ #: dbem_locations.php:225
509
+ #: dbem_locations.php:233
510
+ #: dbem_people.php:90
511
+ msgid "Name"
512
+ msgstr "Nome"
513
+
514
+ #: dbem_events.php:881
515
+ #: dbem_events.php:1215
516
+ msgid "Location"
517
+ msgstr "Luogo"
518
+
519
+ #: dbem_events.php:884
520
+ msgid "Date and time"
521
+ msgstr "Giorno e ora."
522
+
523
+ #: dbem_events.php:896
524
+ msgid "D d M Y"
525
+ msgstr "D d M Y"
526
+
527
+ #: dbem_events.php:1022
528
+ msgid "Daily"
529
+ msgstr "Quotidiana"
530
+
531
+ #: dbem_events.php:1022
532
+ msgid "Weekly"
533
+ msgstr "Settimanale"
534
+
535
+ #: dbem_events.php:1022
536
+ msgid "Monthly"
537
+ msgstr "Mensile"
538
+
539
+ #: dbem_events.php:1023
540
+ msgid "Mon"
541
+ msgstr "Lun"
542
+
543
+ #: dbem_events.php:1023
544
+ msgid "Tue"
545
+ msgstr "Mar"
546
+
547
+ #: dbem_events.php:1023
548
+ msgid "Wed"
549
+ msgstr "Mer"
550
+
551
+ #: dbem_events.php:1023
552
+ msgid "Thu"
553
+ msgstr "Gio"
554
+
555
+ #: dbem_events.php:1023
556
+ msgid "Fri"
557
+ msgstr "Ven"
558
+
559
+ #: dbem_events.php:1023
560
+ msgid "Sat"
561
+ msgstr "Sab"
562
+
563
+ #: dbem_events.php:1023
564
+ msgid "Sun"
565
+ msgstr "Dom"
566
+
567
+ #: dbem_events.php:1025
568
+ msgid "first"
569
+ msgstr "primo"
570
+
571
+ #: dbem_events.php:1025
572
+ msgid "second"
573
+ msgstr "secondo"
574
+
575
+ #: dbem_events.php:1025
576
+ msgid "third"
577
+ msgstr "terzo"
578
+
579
+ #: dbem_events.php:1025
580
+ msgid "fourth"
581
+ msgstr "quarto"
582
+
583
+ #: dbem_events.php:1025
584
+ msgid "last"
585
+ msgstr "ultimo"
586
+
587
+ #: dbem_events.php:1038
588
+ msgid "WARNING: This is a recurrence."
589
+ msgstr "ATTENZIONE: questa è una ricorrenza."
590
+
591
+ #: dbem_events.php:1039
592
+ msgid "Modifying these data all the events linked to this recurrence will be rescheduled"
593
+ msgstr "Se si modificano i dati tutti gli eventi collegati a questa ricorrenza verranno riprogrammati"
594
+
595
+ #: dbem_events.php:1042
596
+ msgid "WARNING: This is a recurring event."
597
+ msgstr "ATTENZIONE: questo è un'evento ricorrente"
598
+
599
+ #: dbem_events.php:1043
600
+ msgid "If you change these data and save, this will become an independent event."
601
+ msgstr "Se si cambiano questi dati e si effettua un salvataggio, questo evento diverrà indipendente."
602
+
603
+ #: dbem_events.php:1055
604
+ msgid "Recurrence"
605
+ msgstr "Ricorrenza"
606
+
607
+ #: dbem_events.php:1066
608
+ msgid "Repeated event"
609
+ msgstr "Eventi ripetuti"
610
+
611
+ #: dbem_events.php:1073
612
+ #: dbem_events.php:1088
613
+ msgid "Every"
614
+ msgstr "Ogni"
615
+
616
+ #: dbem_events.php:1075
617
+ msgid "day"
618
+ msgstr "giorno"
619
+
620
+ #: dbem_events.php:1076
621
+ msgid "days"
622
+ msgstr "giorni"
623
+
624
+ #: dbem_events.php:1077
625
+ msgid "week"
626
+ msgstr "settimana"
627
+
628
+ #: dbem_events.php:1078
629
+ msgid "weeks"
630
+ msgstr "settimane"
631
+
632
+ #: dbem_events.php:1079
633
+ msgid "month"
634
+ msgstr "mese"
635
+
636
+ #: dbem_events.php:1080
637
+ msgid "months"
638
+ msgstr "mesi"
639
+
640
+ #: dbem_events.php:1097
641
+ msgid "Check if your event happens more than once according to a regular pattern"
642
+ msgstr "Selezionare se l'evento si ripete secondo uno schema regolare"
643
+
644
+ #: dbem_events.php:1102
645
+ msgid "This is't a recurrent event"
646
+ msgstr "Questo non è un evento ricorrente"
647
+
648
+ #: dbem_events.php:1119
649
+ msgid "Contact Person"
650
+ msgstr "Responsabile dell'evento"
651
+
652
+ #: dbem_events.php:1121
653
+ msgid "Select..."
654
+ msgstr "Seleziona..."
655
+
656
+ #: dbem_events.php:1132
657
+ msgid "Enable registration for this event"
658
+ msgstr "Abilitare la registrazione per questo evento"
659
+
660
+ #: dbem_events.php:1139
661
+ #: dbem_rsvp.php:247
662
+ msgid "Spaces"
663
+ msgstr "Posti"
664
+
665
+ #: dbem_events.php:1159
666
+ msgid "The event name. Example: Birthday party"
667
+ msgstr "Il nome dell'evento. Esempio: festa di compleanno."
668
+
669
+ #: dbem_events.php:1166
670
+ msgid "Event date"
671
+ msgstr "Date dell'evento"
672
+
673
+ #: dbem_events.php:1166
674
+ msgid "Recurrence dates"
675
+ msgstr "Date della ricorrenza"
676
+
677
+ #: dbem_events.php:1175
678
+ msgid "The event date."
679
+ msgstr "La data dell'evento"
680
+
681
+ #: dbem_events.php:1175
682
+ msgid "The recurrence beginning and end date."
683
+ msgstr "Le date di inizio e fine della ricorrenza"
684
+
685
+ #: dbem_events.php:1185
686
+ msgid "Event time"
687
+ msgstr "Ora dell'evento"
688
+
689
+ #: dbem_events.php:1191
690
+ msgid "The time of the event beginning and end"
691
+ msgstr "L'ora di inizio e fine dell'evento"
692
+
693
+ #: dbem_events.php:1204
694
+ msgid "Coordinates"
695
+ msgstr "Coordinate"
696
+
697
+ #: dbem_events.php:1219
698
+ msgid "Name:"
699
+ msgstr "Nome:"
700
+
701
+ #: dbem_events.php:1222
702
+ #: dbem_locations.php:160
703
+ #: dbem_locations.php:312
704
+ msgid "Map not found"
705
+ msgstr "Mappa non trovata"
706
+
707
+ #: dbem_events.php:1229
708
+ msgid "The name of the location where the event takes place. You can use the name of a venue, a square, etc"
709
+ msgstr "Il nome del locale dove avviene l'evento. È possibile usare il nome di un locale, di una piazza, ecc"
710
+
711
+ #: dbem_events.php:1233
712
+ msgid "Address:"
713
+ msgstr "Indirizzo:"
714
+
715
+ #: dbem_events.php:1237
716
+ msgid "The address of the location where the event takes place. Example: 21, Dominick Street"
717
+ msgstr "L'indirizzo del luogo dove si tiene l'evento. Esempio: Arena"
718
+
719
+ #: dbem_events.php:1241
720
+ msgid "Town:"
721
+ msgstr "Città:"
722
+
723
+ #: dbem_events.php:1245
724
+ msgid "The town where the location is located. If you're using the Google Map integration and want to avoid geotagging ambiguities include the country in the town field. Example: Verona, Italy."
725
+ msgstr "La città dell'evento. Se si utilizza Google Map e si vogliono evitare ambiguità, inserire anche lo stato. Esempio: Verona, Italy"
726
+
727
+ #: dbem_events.php:1257
728
+ msgid "Details"
729
+ msgstr "Dettagli"
730
+
731
+ #: dbem_events.php:1260
732
+ msgid "Details about the event"
733
+ msgstr "Note sull'evento"
734
+
735
+ #: dbem_events.php:1264
736
+ msgid "Submit Event"
737
+ msgstr "Invia evento"
738
+
739
+ #: dbem_events.php:1280
740
+ #: dbem_locations.php:392
741
+ msgid " is missing!"
742
+ msgstr "non è presente!"
743
+
744
+ #: dbem_events.php:1299
745
+ msgid "end date before begin date"
746
+ msgstr "la data finale precede quella iniziale"
747
+
748
+ #: dbem_events.php:1625
749
+ msgid "You cannot enable Google Maps integration without setting an appropriate API key."
750
+ msgstr "Non è possibile abilitare l'integrazione con Google Maps senza impostare una chiave API."
751
+
752
+ #: dbem_events.php:1765
753
+ msgid "Add an event"
754
+ msgstr "Aggiungi un evento"
755
+
756
+ #: dbem_locations.php:4
757
+ msgid "The location name"
758
+ msgstr "Il nome del luogo"
759
+
760
+ #: dbem_locations.php:4
761
+ msgid "The location address"
762
+ msgstr "L'indirizzo del luogo"
763
+
764
+ #: dbem_locations.php:4
765
+ msgid "The location town"
766
+ msgstr "La città del luogo"
767
+
768
+ #: dbem_locations.php:53
769
+ msgid "The location has been updated."
770
+ msgstr "Il luogo è stato aggiornato."
771
+
772
+ #: dbem_locations.php:112
773
+ msgid "Edit location"
774
+ msgstr "Modifica luogo"
775
+
776
+ #: dbem_locations.php:129
777
+ #: dbem_locations.php:278
778
+ msgid "Location name"
779
+ msgstr "Nome del uogo"
780
+
781
+ #: dbem_locations.php:131
782
+ #: dbem_locations.php:280
783
+ msgid "The name of the location"
784
+ msgstr "Il nome del luogo"
785
+
786
+ #: dbem_locations.php:135
787
+ #: dbem_locations.php:284
788
+ msgid "Location address"
789
+ msgstr "Indirizzo del luogo"
790
+
791
+ #: dbem_locations.php:137
792
+ #: dbem_locations.php:286
793
+ msgid "The address of the location"
794
+ msgstr "L'indirizzo del luogo"
795
+
796
+ #: dbem_locations.php:142
797
+ #: dbem_locations.php:290
798
+ msgid "Location town"
799
+ msgstr "Città del luogo"
800
+
801
+ #: dbem_locations.php:144
802
+ msgid "The town where the location is located"
803
+ msgstr "La città del luogo"
804
+
805
+ #: dbem_locations.php:158
806
+ msgid "Location map"
807
+ msgstr "Mappa del luogo"
808
+
809
+ #: dbem_locations.php:165
810
+ #: dbem_locations.php:317
811
+ msgid "Location description"
812
+ msgstr "Descrizione del luogo"
813
+
814
+ #: dbem_locations.php:167
815
+ msgid "A description of the Location. You may include any kind of info here."
816
+ msgstr "Una descrizione del luogo. In quetso campo è possibile includere qualsiasi tipo di informazione."
817
+
818
+ #: dbem_locations.php:171
819
+ #: dbem_locations.php:305
820
+ msgid "Location image"
821
+ msgstr "Immagine del luogo"
822
+
823
+ #: dbem_locations.php:176
824
+ msgid "No image uploaded for this location yet"
825
+ msgstr "Nessuna immagine caricata per questo luogo"
826
+
827
+ #: dbem_locations.php:182
828
+ msgid "Upload/change picture"
829
+ msgstr "Carica/cambia immagine"
830
+
831
+ #: dbem_locations.php:186
832
+ msgid "Update location"
833
+ msgstr "Aggiorna il luogo"
834
+
835
+ #: dbem_locations.php:203
836
+ msgid "Locations"
837
+ msgstr "Luoghi"
838
+
839
+ #: dbem_locations.php:226
840
+ #: dbem_locations.php:234
841
+ msgid "Address"
842
+ msgstr "Indirizzo"
843
+
844
+ #: dbem_locations.php:227
845
+ #: dbem_locations.php:235
846
+ msgid "Town"
847
+ msgstr "Città"
848
+
849
+ #: dbem_locations.php:262
850
+ msgid "No venues have been inserted yet!"
851
+ msgstr "Non sono ancora stati inseriti luoghi!"
852
+
853
+ #: dbem_locations.php:273
854
+ #: dbem_locations.php:322
855
+ msgid "Add location"
856
+ msgstr "Aggiungi un luogo"
857
+
858
+ #: dbem_locations.php:292
859
+ msgid "The town of the location"
860
+ msgstr "La città del luogo."
861
+
862
+ #: dbem_locations.php:307
863
+ msgid "Select an image to upload"
864
+ msgstr "Selezionare un'immagine da caricare."
865
+
866
+ #: dbem_locations.php:319
867
+ msgid "A description of the location. You may include any kind of info here."
868
+ msgstr "Una descrizione del luogo. In questo campo è possibile inserire qualsiasi tipo di informazione."
869
+
870
+ #: dbem_locations.php:400
871
+ msgid "The image file is too big! Maximum size:"
872
+ msgstr "Il file dell'immagine è troppo grande! Dimensione massima:"
873
+
874
+ #: dbem_locations.php:405
875
+ msgid "The image is too big! Maximum size allowed:"
876
+ msgstr "L'immagine è troppo grande! Dimensioni massime:"
877
+
878
+ #: dbem_locations.php:407
879
+ msgid "The image is in a wrong format!"
880
+ msgstr "L'immagine non è nel formato corretto!"
881
+
882
+ #: dbem_locations.php:414
883
+ msgid "Ach, some problems here:"
884
+ msgstr "Accidenti, ci sono dei problemi:"
885
+
886
+ #: dbem_locations.php:475
887
+ msgid "The image could not be loaded"
888
+ msgstr "Impossibile caricare l'immagine"
889
+
890
+ #: dbem_people.php:87
891
+ msgid "Bookings data"
892
+ msgstr "Dati sulle prenotazioni"
893
+
894
+ #: dbem_people.php:91
895
+ msgid "E-mail"
896
+ msgstr "E-mail"
897
+
898
+ #: dbem_people.php:92
899
+ #: dbem_people.php:194
900
+ #: dbem_people.php:197
901
+ msgid "Phone number"
902
+ msgstr "Numero di telefono"
903
+
904
+ #: dbem_people.php:93
905
+ msgid "Seats"
906
+ msgstr "Posti"
907
+
908
+ #: dbem_people.php:106
909
+ msgid "Booked"
910
+ msgstr "Prenotati"
911
+
912
+ #: dbem_people.php:111
913
+ msgid "Available"
914
+ msgstr "Disponibili"
915
+
916
+ #: dbem_people.php:126
917
+ msgid "No people have responded to your events yet!"
918
+ msgstr "Nessuno ha ancora risposto all'evento!"
919
+
920
+ #: dbem_people.php:128
921
+ msgid "This table collects the data about the people who responded to your events"
922
+ msgstr "Questa tabella raccoglie le informazioni sugli utenti che si sono registrati per gli eventi"
923
+
924
+ #: dbem_people.php:199
925
+ msgid "The phone number used by Events Manager when the user is indicated as the contact person for an event."
926
+ msgstr "Il numero telefonico utilizzato da Events Manager quando l'utente è indicato come contatto per l'evento."
927
+
928
+ #: dbem_rsvp.php:88
929
+ msgid "There are no bookings associated to this name and e-mail"
930
+ msgstr "Non ci sono prenotazioni associate a questa combinazione nome/e-mail"
931
+
932
+ #: dbem_rsvp.php:113
933
+ msgid "Your booking has been recorded"
934
+ msgstr "La prenotazione è stata registrata"
935
+
936
+ #: dbem_rsvp.php:120
937
+ msgid "Sorry, there aren't so many seats available!"
938
+ msgstr "Accidenti, non ci sono posti disponibili!"
939
+
940
+ #: dbem_rsvp.php:163
941
+ msgid "Booking deleted"
942
+ msgstr "Prenotazione eliminata."
943
+
944
+ #: dbem_rsvp.php:240
945
+ msgid "responses so far"
946
+ msgstr "risposte finora"
947
+
948
+ #: dbem_rsvp.php:246
949
+ msgid "Responder"
950
+ msgstr "Utente"
951
+
952
+ #: dbem_rsvp.php:252
953
+ msgid "Booked spaces"
954
+ msgstr "Posti prenotati"
955
+
956
+ #: dbem_rsvp.php:253
957
+ msgid "Available spaces"
958
+ msgstr "Posti disponibili"
959
+
960
+ #: dbem_rsvp.php:274
961
+ msgid "Printable view"
962
+ msgstr "Versione stampabile"
963
+
964
+ #: dbem_rsvp.php:282
965
+ msgid "No responses yet!"
966
+ msgstr "Non c'è ancora nessuan risposta!"
967
+
968
+ #: dbem_rsvp.php:353
969
+ msgid "New booking"
970
+ msgstr "Nuova prenotazione"
971
+
972
+ #: dbem_rsvp.php:354
973
+ msgid "Reservation confirmed"
974
+ msgstr "Prenotazione confermata"
975
+
976
+ #: dbem_widgets.php:10
977
+ #: dbem_widgets.php:35
978
+ #: events-manager.php:44
979
+ #: events-manager.php:399
980
+ #: events-manager.php:400
981
+ #: events-manager.php:434
982
+ #: events-manager.php:445
983
+ msgid "Events"
984
+ msgstr "Eventi"
985
+
986
+ #: dbem_widgets.php:19
987
+ #: events-manager.php:50
988
+ #: events-manager.php:392
989
+ msgid "No events"
990
+ msgstr "Nessun evento"
991
+
992
+ #: dbem_widgets.php:78
993
+ #: dbem_widgets.php:156
994
+ msgid "Title"
995
+ msgstr "Titolo"
996
+
997
+ #: dbem_widgets.php:82
998
+ msgid "Number of events"
999
+ msgstr "Numero di eventi"
1000
+
1001
+ #: dbem_widgets.php:86
1002
+ msgid "Scope of the events"
1003
+ msgstr "Ambito degli eventi"
1004
+
1005
+ #: dbem_widgets.php:94
1006
+ msgid "Order of the events"
1007
+ msgstr "Ordine degli eventi"
1008
+
1009
+ #: dbem_widgets.php:96
1010
+ msgid "Ascendant"
1011
+ msgstr "Ascendente"
1012
+
1013
+ #: dbem_widgets.php:97
1014
+ msgid "Descendant"
1015
+ msgstr "Discendente"
1016
+
1017
+ #: dbem_widgets.php:101
1018
+ msgid "List item format"
1019
+ msgstr "Formato degli elementi"
1020
+
1021
+ #: dbem_widgets.php:122
1022
+ msgid "calendar"
1023
+ msgstr "calendario "
1024
+
1025
+ #: dbem_widgets.php:176
1026
+ #: dbem_widgets.php:177
1027
+ msgid "Events List"
1028
+ msgstr "Lista eventi"
1029
+
1030
+ #: dbem_widgets.php:178
1031
+ #: dbem_widgets.php:179
1032
+ msgid "Events Calendar"
1033
+ msgstr "Calendario eventi"
1034
+
1035
+ #: events-manager.php:55
1036
+ msgid "<li>No events in this location</li>"
1037
+ msgstr "<li>Nessun evento in questo luogo</li>"
1038
+
1039
+ #: events-manager.php:384
1040
+ msgid "#_RESPNAME (#_RESPEMAIL) will attend #_NAME on #m #d, #Y. He wants to reserve #_SPACES spaces.<br/> Now there are #_RESERVEDSPACES spaces reserved, #_AVAILABLESPACES are still available.<br/>Yours faithfully,<br/>Events Manager"
1041
+ msgstr "#_RESPNAME (#_RESPEMAIL) parteciperà all'evento #_NAME su #m #d, #Y. Vuole prenotare #_SPACES posti.<br/> Ora ci sono #_RESERVEDSPACES posti prenotati, #_AVAILABLESPACES sono ancora liberi.<br/>A presto,<br/>Events Manager"
1042
+
1043
+ #: events-manager.php:385
1044
+ msgid "Dear #_RESPNAME, <br/>you have successfully reserved #_SPACES space/spaces for #_NAME.<br/>Yours faithfully,<br/> #_CONTACTPERSON"
1045
+ msgstr "#_RESPNAME, <br/>la prenotazione di #_SPACES posto/i a nome di #_NAME è andata a buon fine.<br/>A presto,<br/> #_CONTACTPERSON"
1046
+
1047
+ #: events-manager.php:447
1048
+ msgid "Edit"
1049
+ msgstr "Modifica"
1050
+
1051
+ #: events-manager.php:448
1052
+ msgid "Add new"
1053
+ msgstr "Aggiungi nuovo"
1054
+
1055
+ #~ msgid "Example:"
1056
+ #~ msgstr "Esempio: "
1057
+ #~ msgid "Example: 2008-11-28"
1058
+ #~ msgstr "Esempio: 2008-11-28"
1059
+ #~ msgid "The format the text appearing in the map cloud."
1060
+ #~ msgstr "Il fomato del testo del fumetto che appare sulla mappa."
1061
+ #~ msgid "Follow the previous formatting instructions."
1062
+ #~ msgstr "Seguire le istruzioni di formattazione precedenti."
1063
+ #~ msgid "here"
1064
+ #~ msgstr "questa pagina"
1065
+ #~ msgid "The format of a single location page title."
1066
+ #~ msgstr "Il formato del titolo della pagina di un singolo luogo."
1067
+
1068
+ #, fuzzy
1069
+ #~ msgid "Location picture"
1070
+ #~ msgstr "Luogo"
1071
+ #~ msgid "M_Monday_initial"
1072
+ #~ msgstr "L"
1073
+ #~ msgid "T_Tuesday_initial"
1074
+ #~ msgstr "M"
1075
+ #~ msgid "F_Friday_initial"
1076
+ #~ msgstr "V"
1077
+ #~ msgid "S_Sunday_initial"
1078
+ #~ msgstr "D"
1079
+ #~ msgid "The format of any events in a list."
1080
+ #~ msgstr "Il formato di ciascun evento della lista."
1081
+ #~ msgid ""
1082
+ #~ "Insert one or more of the following placeholders: <code>#_NAME</code>, "
1083
+ #~ "<code>#_LOCATION</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, "
1084
+ #~ "<code>#_NOTES</code>. Use <code>#_LINKEDNAME</code> for the event name "
1085
+ #~ "with a link to the given event page. Use #_URL to print the event URL and "
1086
+ #~ "make your own customised links."
1087
+ #~ msgstr ""
1088
+ #~ "Inserire uno o più dei seguenti segnaposto: <code>#_NAME</code>, "
1089
+ #~ "<code>#_LOCATION</code>, <code>#_ADDRESS</code>, <code>#_TOWN</code>, "
1090
+ #~ "<code>#_NOTES</code>. Utilizzare <code>#_LINKEDNAME</code> per il nome "
1091
+ #~ "dell'evento con un link alla pagina corrispondente. Utilizzare #_URL per "
1092
+ #~ "visualizzare l'URL dell'evento e creare link personalizzati."
1093
+ #~ msgid ""
1094
+ #~ "To insert date and time values, use <a href=\"http://www.php.net/manual/"
1095
+ #~ "en/function.date.php\">PHP time format characters</a> with a # symbol "
1096
+ #~ "before them, i.e. #m. #M, #j, etc. "
1097
+ #~ msgstr ""
1098
+ #~ "Per inserire valori di data e ora, utilizzare i <a href=\"http://www.php."
1099
+ #~ "net/manual/it/function.date.php\">caratteri di stringa formato PHP</a> "
1100
+ #~ "anteponendo ad essi un #, ad esempio #m. #M, #j, etc. "
1101
+ #~ msgid "Use HTML tags as <code>li</code>, <code>br</code>, etc."
1102
+ #~ msgstr ""
1103
+ #~ "Utilizzare liberamente tag HTML come <code>li</code>, <code>br</code>, "
1104
+ #~ "ecc."
1105
+ #~ msgid "Use <code>#_MAP</code> to insert a map."
1106
+ #~ msgstr "Utilizzare <code>#_MAP</code> per inserire una mappa."
1107
+ #~ msgid "The format of the description of each item in the events RSS feed."
1108
+ #~ msgstr "Il formato della descrizione di ciascun elemento nel feed RSS."
1109
+ #~ msgid "ID"
1110
+ #~ msgstr "ID"
1111
+ #~ msgid "Date"
1112
+ #~ msgstr "Data"
1113
+ #~ msgid "Time"
1114
+ #~ msgstr "Ora"
1115
+ #~ msgid "Latitude"
1116
+ #~ msgstr "Latitudine"
1117
+ #~ msgid "Longitude"
1118
+ #~ msgstr "Longitudine"
1119
+ #~ msgid "Are you sure?"
1120
+ #~ msgstr "Sei sicuro?"
1121
+ #~ msgid "Delete"
1122
+ #~ msgstr "Elimina"
1123
+ #~ msgid "Notes"
1124
+ #~ msgstr "Note"
1125
+ #~ msgid ""
1126
+ #~ "You are about to delete this event.\\n 'Cancel' to stop, 'OK' to delete."
1127
+ #~ msgstr ""
1128
+ #~ "Stai per cancellare questo evento.\\n \\'Cancel\\' per annullare "
1129
+ #~ "l'opererazione, \\'Ok\\' per cancellare."
1130
+ #~ msgid "Widget Title"
1131
+ #~ msgstr "Titolo"
1132
+
locations-search.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('../../../wp-load.php');
3
+ $locations = dbem_get_locations();
4
+ $return = array();
5
+
6
+ foreach($locations as $item) {
7
+ $record = array();
8
+ $record['id'] = $item['location_id'];
9
+ $record['name'] = $item['location_name'];
10
+ $record['address'] = $item['location_address'];
11
+ $record['town'] = $item['location_town'];
12
+ $return[] = $record;
13
+ }
14
+
15
+ $q = strtolower($_GET["q"]);
16
+ if (!$q) return;
17
+
18
+ foreach($return as $row) {
19
+
20
+ if (strpos(strtolower($row['name']), $q) !== false) {
21
+ $location = array();
22
+ $rows =array();
23
+ foreach($row as $key => $value)
24
+ $location[] = "'$key' : '".str_replace("'", "\'", $value)."'";
25
+ echo ("{".implode(" , ", $location)." }\n");
26
+ }
27
+
28
+ }
29
+ ?>
phpmailer/class.phpmailer.php ADDED
@@ -0,0 +1,1506 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ////////////////////////////////////////////////////
3
+ // PHPMailer - PHP email class
4
+ //
5
+ // Class for sending email using either
6
+ // sendmail, PHP mail(), or SMTP. Methods are
7
+ // based upon the standard AspEmail(tm) classes.
8
+ //
9
+ // Copyright (C) 2001 - 2003 Brent R. Matzelle
10
+ //
11
+ // License: LGPL, see LICENSE
12
+ ////////////////////////////////////////////////////
13
+
14
+ /**
15
+ * PHPMailer - PHP email transport class
16
+ * @package PHPMailer
17
+ * @author Brent R. Matzelle
18
+ * @copyright 2001 - 2003 Brent R. Matzelle
19
+ */
20
+ class PHPMailer
21
+ {
22
+ /////////////////////////////////////////////////
23
+ // PUBLIC VARIABLES
24
+ /////////////////////////////////////////////////
25
+
26
+ /**
27
+ * Email priority (1 = High, 3 = Normal, 5 = low).
28
+ * @var int
29
+ */
30
+ var $Priority = 3;
31
+
32
+ /**
33
+ * Sets the CharSet of the message.
34
+ * @var string
35
+ */
36
+ var $CharSet = "iso-8859-1";
37
+
38
+ /**
39
+ * Sets the Content-type of the message.
40
+ * @var string
41
+ */
42
+ var $ContentType = "text/plain";
43
+
44
+ /**
45
+ * Sets the Encoding of the message. Options for this are "8bit",
46
+ * "7bit", "binary", "base64", and "quoted-printable".
47
+ * @var string
48
+ */
49
+ var $Encoding = "8bit";
50
+
51
+ /**
52
+ * Holds the most recent mailer error message.
53
+ * @var string
54
+ */
55
+ var $ErrorInfo = "";
56
+
57
+ /**
58
+ * Sets the From email address for the message.
59
+ * @var string
60
+ */
61
+ var $From = "root@localhost";
62
+
63
+ /**
64
+ * Sets the From name of the message.
65
+ * @var string
66
+ */
67
+ var $FromName = "Root User";
68
+
69
+ /**
70
+ * Sets the Sender email (Return-Path) of the message. If not empty,
71
+ * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
72
+ * @var string
73
+ */
74
+ var $Sender = "";
75
+
76
+ /**
77
+ * Sets the Subject of the message.
78
+ * @var string
79
+ */
80
+ var $Subject = "";
81
+
82
+ /**
83
+ * Sets the Body of the message. This can be either an HTML or text body.
84
+ * If HTML then run IsHTML(true).
85
+ * @var string
86
+ */
87
+ var $Body = "";
88
+
89
+ /**
90
+ * Sets the text-only body of the message. This automatically sets the
91
+ * email to multipart/alternative. This body can be read by mail
92
+ * clients that do not have HTML email capability such as mutt. Clients
93
+ * that can read HTML will view the normal Body.
94
+ * @var string
95
+ */
96
+ var $AltBody = "";
97
+
98
+ /**
99
+ * Sets word wrapping on the body of the message to a given number of
100
+ * characters.
101
+ * @var int
102
+ */
103
+ var $WordWrap = 0;
104
+
105
+ /**
106
+ * Method to send mail: ("mail", "sendmail", or "smtp").
107
+ * @var string
108
+ */
109
+ var $Mailer = "mail";
110
+
111
+ /**
112
+ * Sets the path of the sendmail program.
113
+ * @var string
114
+ */
115
+ var $Sendmail = "/usr/sbin/sendmail";
116
+
117
+ /**
118
+ * Path to PHPMailer plugins. This is now only useful if the SMTP class
119
+ * is in a different directory than the PHP include path.
120
+ * @var string
121
+ */
122
+ var $PluginDir = "";
123
+
124
+ /**
125
+ * Holds PHPMailer version.
126
+ * @var string
127
+ */
128
+ var $Version = "1.73";
129
+
130
+ /**
131
+ * Sets the email address that a reading confirmation will be sent.
132
+ * @var string
133
+ */
134
+ var $ConfirmReadingTo = "";
135
+
136
+ /**
137
+ * Sets the hostname to use in Message-Id and Received headers
138
+ * and as default HELO string. If empty, the value returned
139
+ * by SERVER_NAME is used or 'localhost.localdomain'.
140
+ * @var string
141
+ */
142
+ var $Hostname = "";
143
+
144
+ /////////////////////////////////////////////////
145
+ // SMTP VARIABLES
146
+ /////////////////////////////////////////////////
147
+
148
+ /**
149
+ * Sets the SMTP hosts. All hosts must be separated by a
150
+ * semicolon. You can also specify a different port
151
+ * for each host by using this format: [hostname:port]
152
+ * (e.g. "smtp1.example.com:25;smtp2.example.com").
153
+ * Hosts will be tried in order.
154
+ * @var string
155
+ */
156
+ var $Host = "localhost";
157
+
158
+ /**
159
+ * Sets the default SMTP server port.
160
+ * @var int
161
+ */
162
+ var $Port = 25;
163
+
164
+ /**
165
+ * Sets the SMTP HELO of the message (Default is $Hostname).
166
+ * @var string
167
+ */
168
+ var $Helo = "";
169
+
170
+ /**
171
+ * Sets SMTP authentication. Utilizes the Username and Password variables.
172
+ * @var bool
173
+ */
174
+ var $SMTPAuth = false;
175
+
176
+ /**
177
+ * Sets SMTP username.
178
+ * @var string
179
+ */
180
+ var $Username = "";
181
+
182
+ /**
183
+ * Sets SMTP password.
184
+ * @var string
185
+ */
186
+ var $Password = "";
187
+
188
+ /**
189
+ * Sets the SMTP server timeout in seconds. This function will not
190
+ * work with the win32 version.
191
+ * @var int
192
+ */
193
+ var $Timeout = 10;
194
+
195
+ /**
196
+ * Sets SMTP class debugging on or off.
197
+ * @var bool
198
+ */
199
+ var $SMTPDebug = false;
200
+
201
+ /**
202
+ * Prevents the SMTP connection from being closed after each mail
203
+ * sending. If this is set to true then to close the connection
204
+ * requires an explicit call to SmtpClose().
205
+ * @var bool
206
+ */
207
+ var $SMTPKeepAlive = false;
208
+
209
+ /**#@+
210
+ * @access private
211
+ */
212
+ var $smtp = NULL;
213
+ var $to = array();
214
+ var $cc = array();
215
+ var $bcc = array();
216
+ var $ReplyTo = array();
217
+ var $attachment = array();
218
+ var $CustomHeader = array();
219
+ var $message_type = "";
220
+ var $boundary = array();
221
+ var $language = array();
222
+ var $error_count = 0;
223
+ var $LE = "\n";
224
+ /**#@-*/
225
+
226
+ /////////////////////////////////////////////////
227
+ // VARIABLE METHODS
228
+ /////////////////////////////////////////////////
229
+
230
+ /**
231
+ * Sets message type to HTML.
232
+ * @param bool $bool
233
+ * @return void
234
+ */
235
+ function IsHTML($bool) {
236
+ if($bool == true)
237
+ $this->ContentType = "text/html";
238
+ else
239
+ $this->ContentType = "text/plain";
240
+ }
241
+
242
+ /**
243
+ * Sets Mailer to send message using SMTP.
244
+ * @return void
245
+ */
246
+ function IsSMTP() {
247
+ $this->Mailer = "smtp";
248
+ }
249
+
250
+ /**
251
+ * Sets Mailer to send message using PHP mail() function.
252
+ * @return void
253
+ */
254
+ function IsMail() {
255
+ $this->Mailer = "mail";
256
+ }
257
+
258
+ /**
259
+ * Sets Mailer to send message using the $Sendmail program.
260
+ * @return void
261
+ */
262
+ function IsSendmail() {
263
+ $this->Mailer = "sendmail";
264
+ }
265
+
266
+ /**
267
+ * Sets Mailer to send message using the qmail MTA.
268
+ * @return void
269
+ */
270
+ function IsQmail() {
271
+ $this->Sendmail = "/var/qmail/bin/sendmail";
272
+ $this->Mailer = "sendmail";
273
+ }
274
+
275
+
276
+ /////////////////////////////////////////////////
277
+ // RECIPIENT METHODS
278
+ /////////////////////////////////////////////////
279
+
280
+ /**
281
+ * Adds a "To" address.
282
+ * @param string $address
283
+ * @param string $name
284
+ * @return void
285
+ */
286
+ function AddAddress($address, $name = "") {
287
+ $cur = count($this->to);
288
+ $this->to[$cur][0] = trim($address);
289
+ $this->to[$cur][1] = $name;
290
+ }
291
+
292
+ /**
293
+ * Adds a "Cc" address. Note: this function works
294
+ * with the SMTP mailer on win32, not with the "mail"
295
+ * mailer.
296
+ * @param string $address
297
+ * @param string $name
298
+ * @return void
299
+ */
300
+ function AddCC($address, $name = "") {
301
+ $cur = count($this->cc);
302
+ $this->cc[$cur][0] = trim($address);
303
+ $this->cc[$cur][1] = $name;
304
+ }
305
+
306
+ /**
307
+ * Adds a "Bcc" address. Note: this function works
308
+ * with the SMTP mailer on win32, not with the "mail"
309
+ * mailer.
310
+ * @param string $address
311
+ * @param string $name
312
+ * @return void
313
+ */
314
+ function AddBCC($address, $name = "") {
315
+ $cur = count($this->bcc);
316
+ $this->bcc[$cur][0] = trim($address);
317
+ $this->bcc[$cur][1] = $name;
318
+ }
319
+
320
+ /**
321
+ * Adds a "Reply-to" address.
322
+ * @param string $address
323
+ * @param string $name
324
+ * @return void
325
+ */
326
+ function AddReplyTo($address, $name = "") {
327
+ $cur = count($this->ReplyTo);
328
+ $this->ReplyTo[$cur][0] = trim($address);
329
+ $this->ReplyTo[$cur][1] = $name;
330
+ }
331
+
332
+
333
+ /////////////////////////////////////////////////
334
+ // MAIL SENDING METHODS
335
+ /////////////////////////////////////////////////
336
+
337
+ /**
338
+ * Creates message and assigns Mailer. If the message is
339
+ * not sent successfully then it returns false. Use the ErrorInfo
340
+ * variable to view description of the error.
341
+ * @return bool
342
+ */
343
+ function Send() {
344
+ $header = "";
345
+ $body = "";
346
+ $result = true;
347
+
348
+ if((count($this->to) + count($this->cc) + count($this->bcc)) < 1)
349
+ {
350
+ $this->SetError($this->Lang("provide_address"));
351
+ return false;
352
+ }
353
+
354
+ // Set whether the message is multipart/alternative
355
+ if(!empty($this->AltBody))
356
+ $this->ContentType = "multipart/alternative";
357
+
358
+ $this->error_count = 0; // reset errors
359
+ $this->SetMessageType();
360
+ $header .= $this->CreateHeader();
361
+ $body = $this->CreateBody();
362
+
363
+ if($body == "") { return false; }
364
+
365
+ // Choose the mailer
366
+ switch($this->Mailer)
367
+ {
368
+ case "sendmail":
369
+ $result = $this->SendmailSend($header, $body);
370
+ break;
371
+ case "mail":
372
+ $result = $this->MailSend($header, $body);
373
+ break;
374
+ case "smtp":
375
+ $result = $this->SmtpSend($header, $body);
376
+ break;
377
+ default:
378
+ $this->SetError($this->Mailer . $this->Lang("mailer_not_supported"));
379
+ $result = false;
380
+ break;
381
+ }
382
+
383
+ return $result;
384
+ }
385
+
386
+ /**
387
+ * Sends mail using the $Sendmail program.
388
+ * @access private
389
+ * @return bool
390
+ */
391
+ function SendmailSend($header, $body) {
392
+ if ($this->Sender != "")
393
+ $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, $this->Sender);
394
+ else
395
+ $sendmail = sprintf("%s -oi -t", $this->Sendmail);
396
+
397
+ if(!@$mail = popen($sendmail, "w"))
398
+ {
399
+ $this->SetError($this->Lang("execute") . $this->Sendmail);
400
+ return false;
401
+ }
402
+
403
+ fputs($mail, $header);
404
+ fputs($mail, $body);
405
+
406
+ $result = pclose($mail) >> 8 & 0xFF;
407
+ if($result != 0)
408
+ {
409
+ $this->SetError($this->Lang("execute") . $this->Sendmail);
410
+ return false;
411
+ }
412
+
413
+ return true;
414
+ }
415
+
416
+ /**
417
+ * Sends mail using the PHP mail() function.
418
+ * @access private
419
+ * @return bool
420
+ */
421
+ function MailSend($header, $body) {
422
+ $to = "";
423
+ for($i = 0; $i < count($this->to); $i++)
424
+ {
425
+ if($i != 0) { $to .= ", "; }
426
+ $to .= $this->to[$i][0];
427
+ }
428
+
429
+ if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1)
430
+ {
431
+ $old_from = ini_get("sendmail_from");
432
+ ini_set("sendmail_from", $this->Sender);
433
+ $params = sprintf("-oi -f %s", $this->Sender);
434
+ $rt = @mail($to, $this->EncodeHeader($this->Subject), $body,
435
+ $header, $params);
436
+ }
437
+ else
438
+ $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header);
439
+
440
+ if (isset($old_from))
441
+ ini_set("sendmail_from", $old_from);
442
+
443
+ if(!$rt)
444
+ {
445
+ $this->SetError($this->Lang("instantiate"));
446
+ return false;
447
+ }
448
+
449
+ return true;
450
+ }
451
+
452
+ /**
453
+ * Sends mail via SMTP using PhpSMTP (Author:
454
+ * Chris Ryan). Returns bool. Returns false if there is a
455
+ * bad MAIL FROM, RCPT, or DATA input.
456
+ * @access private
457
+ * @return bool
458
+ */
459
+ function SmtpSend($header, $body) {
460
+ include_once($this->PluginDir . "class.smtp.php");
461
+ $error = "";
462
+ $bad_rcpt = array();
463
+
464
+ if(!$this->SmtpConnect())
465
+ return false;
466
+
467
+ $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender;
468
+ if(!$this->smtp->Mail($smtp_from))
469
+ {
470
+ $error = $this->Lang("from_failed") . $smtp_from;
471
+ $this->SetError($error);
472
+ $this->smtp->Reset();
473
+ return false;
474
+ }
475
+
476
+ // Attempt to send attach all recipients
477
+ for($i = 0; $i < count($this->to); $i++)
478
+ {
479
+ if(!$this->smtp->Recipient($this->to[$i][0]))
480
+ $bad_rcpt[] = $this->to[$i][0];
481
+ }
482
+ for($i = 0; $i < count($this->cc); $i++)
483
+ {
484
+ if(!$this->smtp->Recipient($this->cc[$i][0]))
485
+ $bad_rcpt[] = $this->cc[$i][0];
486
+ }
487
+ for($i = 0; $i < count($this->bcc); $i++)
488
+ {
489
+ if(!$this->smtp->Recipient($this->bcc[$i][0]))
490
+ $bad_rcpt[] = $this->bcc[$i][0];
491
+ }
492
+
493
+ if(count($bad_rcpt) > 0) // Create error message
494
+ {
495
+ for($i = 0; $i < count($bad_rcpt); $i++)
496
+ {
497
+ if($i != 0) { $error .= ", "; }
498
+ $error .= $bad_rcpt[$i];
499
+ }
500
+ $error = $this->Lang("recipients_failed") . $error;
501
+ $this->SetError($error);
502
+ $this->smtp->Reset();
503
+ return false;
504
+ }
505
+
506
+ if(!$this->smtp->Data($header . $body))
507
+ {
508
+ $this->SetError($this->Lang("data_not_accepted"));
509
+ $this->smtp->Reset();
510
+ return false;
511
+ }
512
+ if($this->SMTPKeepAlive == true)
513
+ $this->smtp->Reset();
514
+ else
515
+ $this->SmtpClose();
516
+
517
+ return true;
518
+ }
519
+
520
+ /**
521
+ * Initiates a connection to an SMTP server. Returns false if the
522
+ * operation failed.
523
+ * @access private
524
+ * @return bool
525
+ */
526
+ function SmtpConnect() {
527
+ if($this->smtp == NULL) { $this->smtp = new SMTP(); }
528
+
529
+ $this->smtp->do_debug = $this->SMTPDebug;
530
+ $hosts = explode(";", $this->Host);
531
+ $index = 0;
532
+ $connection = ($this->smtp->Connected());
533
+
534
+ // Retry while there is no connection
535
+ while($index < count($hosts) && $connection == false)
536
+ {
537
+ if(strstr($hosts[$index], ":"))
538
+ {
539
+ $hostA = explode(':', $hosts[$index]);
540
+ if (is_numeric(end($hostA)))
541
+ $port = array_pop($hostA);
542
+ else
543
+ $port = $this->Port;
544
+ $host = implode(':', $hostA);
545
+ }
546
+ else
547
+ {
548
+ $host = $hosts[$index];
549
+ $port = $this->Port;
550
+ }
551
+
552
+ if($this->smtp->Connect($host, $port, $this->Timeout))
553
+ {
554
+ if ($this->Helo != '')
555
+ $this->smtp->Hello($this->Helo);
556
+ else
557
+ $this->smtp->Hello($this->ServerHostname());
558
+
559
+ if($this->SMTPAuth)
560
+ {
561
+ if(!$this->smtp->Authenticate($this->Username,
562
+ $this->Password))
563
+ {
564
+ $this->SetError($this->Lang("authenticate"));
565
+ $this->smtp->Reset();
566
+ $connection = false;
567
+ }
568
+ }
569
+ $connection = true;
570
+ }
571
+ $index++;
572
+ }
573
+ if(!$connection)
574
+ $this->SetError($this->Lang("connect_host"));
575
+
576
+ return $connection;
577
+ }
578
+
579
+ /**
580
+ * Closes the active SMTP session if one exists.
581
+ * @return void
582
+ */
583
+ function SmtpClose() {
584
+ if($this->smtp != NULL)
585
+ {
586
+ if($this->smtp->Connected())
587
+ {
588
+ $this->smtp->Quit();
589
+ $this->smtp->Close();
590
+ }
591
+ }
592
+ }
593
+
594
+ /**
595
+ * Sets the language for all class error messages. Returns false
596
+ * if it cannot load the language file. The default language type
597
+ * is English.
598
+ * @param string $lang_type Type of language (e.g. Portuguese: "br")
599
+ * @param string $lang_path Path to the language file directory
600
+ * @access public
601
+ * @return bool
602
+ */
603
+ function SetLanguage($lang_type, $lang_path = "language/") {
604
+ if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php'))
605
+ include($lang_path.'phpmailer.lang-'.$lang_type.'.php');
606
+ else if(file_exists($lang_path.'phpmailer.lang-en.php'))
607
+ include($lang_path.'phpmailer.lang-en.php');
608
+ else
609
+ {
610
+ $this->SetError("Could not load language file");
611
+ return false;
612
+ }
613
+ $this->language = $PHPMAILER_LANG;
614
+
615
+ return true;
616
+ }
617
+
618
+ /////////////////////////////////////////////////
619
+ // MESSAGE CREATION METHODS
620
+ /////////////////////////////////////////////////
621
+
622
+ /**
623
+ * Creates recipient headers.
624
+ * @access private
625
+ * @return string
626
+ */
627
+ function AddrAppend($type, $addr) {
628
+ $addr_str = $type . ": ";
629
+ $addr_str .= $this->AddrFormat($addr[0]);
630
+ if(count($addr) > 1)
631
+ {
632
+ for($i = 1; $i < count($addr); $i++)
633
+ $addr_str .= ", " . $this->AddrFormat($addr[$i]);
634
+ }
635
+ $addr_str .= $this->LE;
636
+
637
+ return $addr_str;
638
+ }
639
+
640
+ /**
641
+ * Formats an address correctly.
642
+ * @access private
643
+ * @return string
644
+ */
645
+ function AddrFormat($addr) {
646
+ if(empty($addr[1]))
647
+ $formatted = $addr[0];
648
+ else
649
+ {
650
+ $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" .
651
+ $addr[0] . ">";
652
+ }
653
+
654
+ return $formatted;
655
+ }
656
+
657
+ /**
658
+ * Wraps message for use with mailers that do not
659
+ * automatically perform wrapping and for quoted-printable.
660
+ * Original written by philippe.
661
+ * @access private
662
+ * @return string
663
+ */
664
+ function WrapText($message, $length, $qp_mode = false) {
665
+ $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
666
+
667
+ $message = $this->FixEOL($message);
668
+ if (substr($message, -1) == $this->LE)
669
+ $message = substr($message, 0, -1);
670
+
671
+ $line = explode($this->LE, $message);
672
+ $message = "";
673
+ for ($i=0 ;$i < count($line); $i++)
674
+ {
675
+ $line_part = explode(" ", $line[$i]);
676
+ $buf = "";
677
+ for ($e = 0; $e<count($line_part); $e++)
678
+ {
679
+ $word = $line_part[$e];
680
+ if ($qp_mode and (strlen($word) > $length))
681
+ {
682
+ $space_left = $length - strlen($buf) - 1;
683
+ if ($e != 0)
684
+ {
685
+ if ($space_left > 20)
686
+ {
687
+ $len = $space_left;
688
+ if (substr($word, $len - 1, 1) == "=")
689
+ $len--;
690
+ elseif (substr($word, $len - 2, 1) == "=")
691
+ $len -= 2;
692
+ $part = substr($word, 0, $len);
693
+ $word = substr($word, $len);
694
+ $buf .= " " . $part;
695
+ $message .= $buf . sprintf("=%s", $this->LE);
696
+ }
697
+ else
698
+ {
699
+ $message .= $buf . $soft_break;
700
+ }
701
+ $buf = "";
702
+ }
703
+ while (strlen($word) > 0)
704
+ {
705
+ $len = $length;
706
+ if (substr($word, $len - 1, 1) == "=")
707
+ $len--;
708
+ elseif (substr($word, $len - 2, 1) == "=")
709
+ $len -= 2;
710
+ $part = substr($word, 0, $len);
711
+ $word = substr($word, $len);
712
+
713
+ if (strlen($word) > 0)
714
+ $message .= $part . sprintf("=%s", $this->LE);
715
+ else
716
+ $buf = $part;
717
+ }
718
+ }
719
+ else
720
+ {
721
+ $buf_o = $buf;
722
+ $buf .= ($e == 0) ? $word : (" " . $word);
723
+
724
+ if (strlen($buf) > $length and $buf_o != "")
725
+ {
726
+ $message .= $buf_o . $soft_break;
727
+ $buf = $word;
728
+ }
729
+ }
730
+ }
731
+ $message .= $buf . $this->LE;
732
+ }
733
+
734
+ return $message;
735
+ }
736
+
737
+ /**
738
+ * Set the body wrapping.
739
+ * @access private
740
+ * @return void
741
+ */
742
+ function SetWordWrap() {
743
+ if($this->WordWrap < 1)
744
+ return;
745
+
746
+ switch($this->message_type)
747
+ {
748
+ case "alt":
749
+ // fall through
750
+ case "alt_attachments":
751
+ $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
752
+ break;
753
+ default:
754
+ $this->Body = $this->WrapText($this->Body, $this->WordWrap);
755
+ break;
756
+ }
757
+ }
758
+
759
+ /**
760
+ * Assembles message header.
761
+ * @access private
762
+ * @return string
763
+ */
764
+ function CreateHeader() {
765
+ $result = "";
766
+
767
+ // Set the boundaries
768
+ $uniq_id = md5(uniqid(time()));
769
+ $this->boundary[1] = "b1_" . $uniq_id;
770
+ $this->boundary[2] = "b2_" . $uniq_id;
771
+
772
+ $result .= $this->HeaderLine("Date", $this->RFCDate());
773
+ if($this->Sender == "")
774
+ $result .= $this->HeaderLine("Return-Path", trim($this->From));
775
+ else
776
+ $result .= $this->HeaderLine("Return-Path", trim($this->Sender));
777
+
778
+ // To be created automatically by mail()
779
+ if($this->Mailer != "mail")
780
+ {
781
+ if(count($this->to) > 0)
782
+ $result .= $this->AddrAppend("To", $this->to);
783
+ else if (count($this->cc) == 0)
784
+ $result .= $this->HeaderLine("To", "undisclosed-recipients:;");
785
+ if(count($this->cc) > 0)
786
+ $result .= $this->AddrAppend("Cc", $this->cc);
787
+ }
788
+
789
+ $from = array();
790
+ $from[0][0] = trim($this->From);
791
+ $from[0][1] = $this->FromName;
792
+ $result .= $this->AddrAppend("From", $from);
793
+
794
+ // sendmail and mail() extract Bcc from the header before sending
795
+ if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0))
796
+ $result .= $this->AddrAppend("Bcc", $this->bcc);
797
+
798
+ if(count($this->ReplyTo) > 0)
799
+ $result .= $this->AddrAppend("Reply-to", $this->ReplyTo);
800
+
801
+ // mail() sets the subject itself
802
+ if($this->Mailer != "mail")
803
+ $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject)));
804
+
805
+ $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
806
+ $result .= $this->HeaderLine("X-Priority", $this->Priority);
807
+ $result .= $this->HeaderLine("X-Mailer", "PHPMailer [version " . $this->Version . "]");
808
+
809
+ if($this->ConfirmReadingTo != "")
810
+ {
811
+ $result .= $this->HeaderLine("Disposition-Notification-To",
812
+ "<" . trim($this->ConfirmReadingTo) . ">");
813
+ }
814
+
815
+ // Add custom headers
816
+ for($index = 0; $index < count($this->CustomHeader); $index++)
817
+ {
818
+ $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]),
819
+ $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
820
+ }
821
+ $result .= $this->HeaderLine("MIME-Version", "1.0");
822
+
823
+ switch($this->message_type)
824
+ {
825
+ case "plain":
826
+ $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding);
827
+ $result .= sprintf("Content-Type: %s; charset=\"%s\"",
828
+ $this->ContentType, $this->CharSet);
829
+ break;
830
+ case "attachments":
831
+ // fall through
832
+ case "alt_attachments":
833
+ if($this->InlineImageExists())
834
+ {
835
+ $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s",
836
+ "multipart/related", $this->LE, $this->LE,
837
+ $this->boundary[1], $this->LE);
838
+ }
839
+ else
840
+ {
841
+ $result .= $this->HeaderLine("Content-Type", "multipart/mixed;");
842
+ $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
843
+ }
844
+ break;
845
+ case "alt":
846
+ $result .= $this->HeaderLine("Content-Type", "multipart/alternative;");
847
+ $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
848
+ break;
849
+ }
850
+
851
+ if($this->Mailer != "mail")
852
+ $result .= $this->LE.$this->LE;
853
+
854
+ return $result;
855
+ }
856
+
857
+ /**
858
+ * Assembles the message body. Returns an empty string on failure.
859
+ * @access private
860
+ * @return string
861
+ */
862
+ function CreateBody() {
863
+ $result = "";
864
+
865
+ $this->SetWordWrap();
866
+
867
+ switch($this->message_type)
868
+ {
869
+ case "alt":
870
+ $result .= $this->GetBoundary($this->boundary[1], "",
871
+ "text/plain", "");
872
+ $result .= $this->EncodeString($this->AltBody, $this->Encoding);
873
+ $result .= $this->LE.$this->LE;
874
+ $result .= $this->GetBoundary($this->boundary[1], "",
875
+ "text/html", "");
876
+
877
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
878
+ $result .= $this->LE.$this->LE;
879
+
880
+ $result .= $this->EndBoundary($this->boundary[1]);
881
+ break;
882
+ case "plain":
883
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
884
+ break;
885
+ case "attachments":
886
+ $result .= $this->GetBoundary($this->boundary[1], "", "", "");
887
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
888
+ $result .= $this->LE;
889
+
890
+ $result .= $this->AttachAll();
891
+ break;
892
+ case "alt_attachments":
893
+ $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
894
+ $result .= sprintf("Content-Type: %s;%s" .
895
+ "\tboundary=\"%s\"%s",
896
+ "multipart/alternative", $this->LE,
897
+ $this->boundary[2], $this->LE.$this->LE);
898
+
899
+ // Create text body
900
+ $result .= $this->GetBoundary($this->boundary[2], "",
901
+ "text/plain", "") . $this->LE;
902
+
903
+ $result .= $this->EncodeString($this->AltBody, $this->Encoding);
904
+ $result .= $this->LE.$this->LE;
905
+
906
+ // Create the HTML body
907
+ $result .= $this->GetBoundary($this->boundary[2], "",
908
+ "text/html", "") . $this->LE;
909
+
910
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
911
+ $result .= $this->LE.$this->LE;
912
+
913
+ $result .= $this->EndBoundary($this->boundary[2]);
914
+
915
+ $result .= $this->AttachAll();
916
+ break;
917
+ }
918
+ if($this->IsError())
919
+ $result = "";
920
+
921
+ return $result;
922
+ }
923
+
924
+ /**
925
+ * Returns the start of a message boundary.
926
+ * @access private
927
+ */
928
+ function GetBoundary($boundary, $charSet, $contentType, $encoding) {
929
+ $result = "";
930
+ if($charSet == "") { $charSet = $this->CharSet; }
931
+ if($contentType == "") { $contentType = $this->ContentType; }
932
+ if($encoding == "") { $encoding = $this->Encoding; }
933
+
934
+ $result .= $this->TextLine("--" . $boundary);
935
+ $result .= sprintf("Content-Type: %s; charset = \"%s\"",
936
+ $contentType, $charSet);
937
+ $result .= $this->LE;
938
+ $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding);
939
+ $result .= $this->LE;
940
+
941
+ return $result;
942
+ }
943
+
944
+ /**
945
+ * Returns the end of a message boundary.
946
+ * @access private
947
+ */
948
+ function EndBoundary($boundary) {
949
+ return $this->LE . "--" . $boundary . "--" . $this->LE;
950
+ }
951
+
952
+ /**
953
+ * Sets the message type.
954
+ * @access private
955
+ * @return void
956
+ */
957
+ function SetMessageType() {
958
+ if(count($this->attachment) < 1 && strlen($this->AltBody) < 1)
959
+ $this->message_type = "plain";
960
+ else
961
+ {
962
+ if(count($this->attachment) > 0)
963
+ $this->message_type = "attachments";
964
+ if(strlen($this->AltBody) > 0 && count($this->attachment) < 1)
965
+ $this->message_type = "alt";
966
+ if(strlen($this->AltBody) > 0 && count($this->attachment) > 0)
967
+ $this->message_type = "alt_attachments";
968
+ }
969
+ }
970
+
971
+ /**
972
+ * Returns a formatted header line.
973
+ * @access private
974
+ * @return string
975
+ */
976
+ function HeaderLine($name, $value) {
977
+ return $name . ": " . $value . $this->LE;
978
+ }
979
+
980
+ /**
981
+ * Returns a formatted mail line.
982
+ * @access private
983
+ * @return string
984
+ */
985
+ function TextLine($value) {
986
+ return $value . $this->LE;
987
+ }
988
+
989
+ /////////////////////////////////////////////////
990
+ // ATTACHMENT METHODS
991
+ /////////////////////////////////////////////////
992
+
993
+ /**
994
+ * Adds an attachment from a path on the filesystem.
995
+ * Returns false if the file could not be found
996
+ * or accessed.
997
+ * @param string $path Path to the attachment.
998
+ * @param string $name Overrides the attachment name.
999
+ * @param string $encoding File encoding (see $Encoding).
1000
+ * @param string $type File extension (MIME) type.
1001
+ * @return bool
1002
+ */
1003
+ function AddAttachment($path, $name = "", $encoding = "base64",
1004
+ $type = "application/octet-stream") {
1005
+ if(!@is_file($path))
1006
+ {
1007
+ $this->SetError($this->Lang("file_access") . $path);
1008
+ return false;
1009
+ }
1010
+
1011
+ $filename = basename($path);
1012
+ if($name == "")
1013
+ $name = $filename;
1014
+
1015
+ $cur = count($this->attachment);
1016
+ $this->attachment[$cur][0] = $path;
1017
+ $this->attachment[$cur][1] = $filename;
1018
+ $this->attachment[$cur][2] = $name;
1019
+ $this->attachment[$cur][3] = $encoding;
1020
+ $this->attachment[$cur][4] = $type;
1021
+ $this->attachment[$cur][5] = false; // isStringAttachment
1022
+ $this->attachment[$cur][6] = "attachment";
1023
+ $this->attachment[$cur][7] = 0;
1024
+
1025
+ return true;
1026
+ }
1027
+
1028
+ /**
1029
+ * Attaches all fs, string, and binary attachments to the message.
1030
+ * Returns an empty string on failure.
1031
+ * @access private
1032
+ * @return string
1033
+ */
1034
+ function AttachAll() {
1035
+ // Return text of body
1036
+ $mime = array();
1037
+
1038
+ // Add all attachments
1039
+ for($i = 0; $i < count($this->attachment); $i++)
1040
+ {
1041
+ // Check for string attachment
1042
+ $bString = $this->attachment[$i][5];
1043
+ if ($bString)
1044
+ $string = $this->attachment[$i][0];
1045
+ else
1046
+ $path = $this->attachment[$i][0];
1047
+
1048
+ $filename = $this->attachment[$i][1];
1049
+ $name = $this->attachment[$i][2];
1050
+ $encoding = $this->attachment[$i][3];
1051
+ $type = $this->attachment[$i][4];
1052
+ $disposition = $this->attachment[$i][6];
1053
+ $cid = $this->attachment[$i][7];
1054
+
1055
+ $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
1056
+ $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);
1057
+ $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
1058
+
1059
+ if($disposition == "inline")
1060
+ $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
1061
+
1062
+ $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s",
1063
+ $disposition, $name, $this->LE.$this->LE);
1064
+
1065
+ // Encode as string attachment
1066
+ if($bString)
1067
+ {
1068
+ $mime[] = $this->EncodeString($string, $encoding);
1069
+ if($this->IsError()) { return ""; }
1070
+ $mime[] = $this->LE.$this->LE;
1071
+ }
1072
+ else
1073
+ {
1074
+ $mime[] = $this->EncodeFile($path, $encoding);
1075
+ if($this->IsError()) { return ""; }
1076
+ $mime[] = $this->LE.$this->LE;
1077
+ }
1078
+ }
1079
+
1080
+ $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
1081
+
1082
+ return join("", $mime);
1083
+ }
1084
+
1085
+ /**
1086
+ * Encodes attachment in requested format. Returns an
1087
+ * empty string on failure.
1088
+ * @access private
1089
+ * @return string
1090
+ */
1091
+ function EncodeFile ($path, $encoding = "base64") {
1092
+ if(!@$fd = fopen($path, "rb"))
1093
+ {
1094
+ $this->SetError($this->Lang("file_open") . $path);
1095
+ return "";
1096
+ }
1097
+ $magic_quotes = get_magic_quotes_runtime();
1098
+ set_magic_quotes_runtime(0);
1099
+ $file_buffer = fread($fd, filesize($path));
1100
+ $file_buffer = $this->EncodeString($file_buffer, $encoding);
1101
+ fclose($fd);
1102
+ set_magic_quotes_runtime($magic_quotes);
1103
+
1104
+ return $file_buffer;
1105
+ }
1106
+
1107
+ /**
1108
+ * Encodes string to requested format. Returns an
1109
+ * empty string on failure.
1110
+ * @access private
1111
+ * @return string
1112
+ */
1113
+ function EncodeString ($str, $encoding = "base64") {
1114
+ $encoded = "";
1115
+ switch(strtolower($encoding)) {
1116
+ case "base64":
1117
+ // chunk_split is found in PHP >= 3.0.6
1118
+ $encoded = chunk_split(base64_encode($str), 76, $this->LE);
1119
+ break;
1120
+ case "7bit":
1121
+ case "8bit":
1122
+ $encoded = $this->FixEOL($str);
1123
+ if (substr($encoded, -(strlen($this->LE))) != $this->LE)
1124
+ $encoded .= $this->LE;
1125
+ break;
1126
+ case "binary":
1127
+ $encoded = $str;
1128
+ break;
1129
+ case "quoted-printable":
1130
+ $encoded = $this->EncodeQP($str);
1131
+ break;
1132
+ default:
1133
+ $this->SetError($this->Lang("encoding") . $encoding);
1134
+ break;
1135
+ }
1136
+ return $encoded;
1137
+ }
1138
+
1139
+ /**
1140
+ * Encode a header string to best of Q, B, quoted or none.
1141
+ * @access private
1142
+ * @return string
1143
+ */
1144
+ function EncodeHeader ($str, $position = 'text') {
1145
+ $x = 0;
1146
+
1147
+ switch (strtolower($position)) {
1148
+ case 'phrase':
1149
+ if (!preg_match('/[\200-\377]/', $str)) {
1150
+ // Can't use addslashes as we don't know what value has magic_quotes_sybase.
1151
+ $encoded = addcslashes($str, "\0..\37\177\\\"");
1152
+
1153
+ if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str))
1154
+ return ($encoded);
1155
+ else
1156
+ return ("\"$encoded\"");
1157
+ }
1158
+ $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
1159
+ break;
1160
+ case 'comment':
1161
+ $x = preg_match_all('/[()"]/', $str, $matches);
1162
+ // Fall-through
1163
+ case 'text':
1164
+ default:
1165
+ $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
1166
+ break;
1167
+ }
1168
+
1169
+ if ($x == 0)
1170
+ return ($str);
1171
+
1172
+ $maxlen = 75 - 7 - strlen($this->CharSet);
1173
+ // Try to select the encoding which should produce the shortest output
1174
+ if (strlen($str)/3 < $x) {
1175
+ $encoding = 'B';
1176
+ $encoded = base64_encode($str);
1177
+ $maxlen -= $maxlen % 4;
1178
+ $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
1179
+ } else {
1180
+ $encoding = 'Q';
1181
+ $encoded = $this->EncodeQ($str, $position);
1182
+ $encoded = $this->WrapText($encoded, $maxlen, true);
1183
+ $encoded = str_replace("=".$this->LE, "\n", trim($encoded));
1184
+ }
1185
+
1186
+ $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
1187
+ $encoded = trim(str_replace("\n", $this->LE, $encoded));
1188
+
1189
+ return $encoded;
1190
+ }
1191
+
1192
+ /**
1193
+ * Encode string to quoted-printable.
1194
+ * @access private
1195
+ * @return string
1196
+ */
1197
+ function EncodeQP ($str) {
1198
+ $encoded = $this->FixEOL($str);
1199
+ if (substr($encoded, -(strlen($this->LE))) != $this->LE)
1200
+ $encoded .= $this->LE;
1201
+
1202
+ // Replace every high ascii, control and = characters
1203
+ $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e',
1204
+ "'='.sprintf('%02X', ord('\\1'))", $encoded);
1205
+ // Replace every spaces and tabs when it's the last character on a line
1206
+ $encoded = preg_replace("/([\011\040])".$this->LE."/e",
1207
+ "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded);
1208
+
1209
+ // Maximum line length of 76 characters before CRLF (74 + space + '=')
1210
+ $encoded = $this->WrapText($encoded, 74, true);
1211
+
1212
+ return $encoded;
1213
+ }
1214
+
1215
+ /**
1216
+ * Encode string to q encoding.
1217
+ * @access private
1218
+ * @return string
1219
+ */
1220
+ function EncodeQ ($str, $position = "text") {
1221
+ // There should not be any EOL in the string
1222
+ $encoded = preg_replace("[\r\n]", "", $str);
1223
+
1224
+ switch (strtolower($position)) {
1225
+ case "phrase":
1226
+ $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1227
+ break;
1228
+ case "comment":
1229
+ $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1230
+ case "text":
1231
+ default:
1232
+ // Replace every high ascii, control =, ? and _ characters
1233
+ $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
1234
+ "'='.sprintf('%02X', ord('\\1'))", $encoded);
1235
+ break;
1236
+ }
1237
+
1238
+ // Replace every spaces to _ (more readable than =20)
1239
+ $encoded = str_replace(" ", "_", $encoded);
1240
+
1241
+ return $encoded;
1242
+ }
1243
+
1244
+ /**
1245
+ * Adds a string or binary attachment (non-filesystem) to the list.
1246
+ * This method can be used to attach ascii or binary data,
1247
+ * such as a BLOB record from a database.
1248
+ * @param string $string String attachment data.
1249
+ * @param string $filename Name of the attachment.
1250
+ * @param string $encoding File encoding (see $Encoding).
1251
+ * @param string $type File extension (MIME) type.
1252
+ * @return void
1253
+ */
1254
+ function AddStringAttachment($string, $filename, $encoding = "base64",
1255
+ $type = "application/octet-stream") {
1256
+ // Append to $attachment array
1257
+ $cur = count($this->attachment);
1258
+ $this->attachment[$cur][0] = $string;
1259
+ $this->attachment[$cur][1] = $filename;
1260
+ $this->attachment[$cur][2] = $filename;
1261
+ $this->attachment[$cur][3] = $encoding;
1262
+ $this->attachment[$cur][4] = $type;
1263
+ $this->attachment[$cur][5] = true; // isString
1264
+ $this->attachment[$cur][6] = "attachment";
1265
+ $this->attachment[$cur][7] = 0;
1266
+ }
1267
+
1268
+ /**
1269
+ * Adds an embedded attachment. This can include images, sounds, and
1270
+ * just about any other document. Make sure to set the $type to an
1271
+ * image type. For JPEG images use "image/jpeg" and for GIF images
1272
+ * use "image/gif".
1273
+ * @param string $path Path to the attachment.
1274
+ * @param string $cid Content ID of the attachment. Use this to identify
1275
+ * the Id for accessing the image in an HTML form.
1276
+ * @param string $name Overrides the attachment name.
1277
+ * @param string $encoding File encoding (see $Encoding).
1278
+ * @param string $type File extension (MIME) type.
1279
+ * @return bool
1280
+ */
1281
+ function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64",
1282
+ $type = "application/octet-stream") {
1283
+
1284
+ if(!@is_file($path))
1285
+ {
1286
+ $this->SetError($this->Lang("file_access") . $path);
1287
+ return false;
1288
+ }
1289
+
1290
+ $filename = basename($path);
1291
+ if($name == "")
1292
+ $name = $filename;
1293
+
1294
+ // Append to $attachment array
1295
+ $cur = count($this->attachment);
1296
+ $this->attachment[$cur][0] = $path;
1297
+ $this->attachment[$cur][1] = $filename;
1298
+ $this->attachment[$cur][2] = $name;
1299
+ $this->attachment[$cur][3] = $encoding;
1300
+ $this->attachment[$cur][4] = $type;
1301
+ $this->attachment[$cur][5] = false; // isStringAttachment
1302
+ $this->attachment[$cur][6] = "inline";
1303
+ $this->attachment[$cur][7] = $cid;
1304
+
1305
+ return true;
1306
+ }
1307
+
1308
+ /**
1309
+ * Returns true if an inline attachment is present.
1310
+ * @access private
1311
+ * @return bool
1312
+ */
1313
+ function InlineImageExists() {
1314
+ $result = false;
1315
+ for($i = 0; $i < count($this->attachment); $i++)
1316
+ {
1317
+ if($this->attachment[$i][6] == "inline")
1318
+ {
1319
+ $result = true;
1320
+ break;
1321
+ }
1322
+ }
1323
+
1324
+ return $result;
1325
+ }
1326
+
1327
+ /////////////////////////////////////////////////
1328
+ // MESSAGE RESET METHODS
1329
+ /////////////////////////////////////////////////
1330
+
1331
+ /**
1332
+ * Clears all recipients assigned in the TO array. Returns void.
1333
+ * @return void
1334
+ */
1335
+ function ClearAddresses() {
1336
+ $this->to = array();
1337
+ }
1338
+
1339
+ /**
1340
+ * Clears all recipients assigned in the CC array. Returns void.
1341
+ * @return void
1342
+ */
1343
+ function ClearCCs() {
1344
+ $this->cc = array();
1345
+ }
1346
+
1347
+ /**
1348
+ * Clears all recipients assigned in the BCC array. Returns void.
1349
+ * @return void
1350
+ */
1351
+ function ClearBCCs() {
1352
+ $this->bcc = array();
1353
+ }
1354
+
1355
+ /**
1356
+ * Clears all recipients assigned in the ReplyTo array. Returns void.
1357
+ * @return void
1358
+ */
1359
+ function ClearReplyTos() {
1360
+ $this->ReplyTo = array();
1361
+ }
1362
+
1363
+ /**
1364
+ * Clears all recipients assigned in the TO, CC and BCC
1365
+ * array. Returns void.
1366
+ * @return void
1367
+ */
1368
+ function ClearAllRecipients() {
1369
+ $this->to = array();
1370
+ $this->cc = array();
1371
+ $this->bcc = array();
1372
+ }
1373
+
1374
+ /**
1375
+ * Clears all previously set filesystem, string, and binary
1376
+ * attachments. Returns void.
1377
+ * @return void
1378
+ */
1379
+ function ClearAttachments() {
1380
+ $this->attachment = array();
1381
+ }
1382
+
1383
+ /**
1384
+ * Clears all custom headers. Returns void.
1385
+ * @return void
1386
+ */
1387
+ function ClearCustomHeaders() {
1388
+ $this->CustomHeader = array();
1389
+ }
1390
+
1391
+
1392
+ /////////////////////////////////////////////////
1393
+ // MISCELLANEOUS METHODS
1394
+ /////////////////////////////////////////////////
1395
+
1396
+ /**
1397
+ * Adds the error message to the error container.
1398
+ * Returns void.
1399
+ * @access private
1400
+ * @return void
1401
+ */
1402
+ function SetError($msg) {
1403
+ $this->error_count++;
1404
+ $this->ErrorInfo = $msg;
1405
+ }
1406
+
1407
+ /**
1408
+ * Returns the proper RFC 822 formatted date.
1409
+ * @access private
1410
+ * @return string
1411
+ */
1412
+ function RFCDate() {
1413
+ $tz = date("Z");
1414
+ $tzs = ($tz < 0) ? "-" : "+";
1415
+ $tz = abs($tz);
1416
+ $tz = ($tz/3600)*100 + ($tz%3600)/60;
1417
+ $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz);
1418
+
1419
+ return $result;
1420
+ }
1421
+
1422
+ /**
1423
+ * Returns the appropriate server variable. Should work with both
1424
+ * PHP 4.1.0+ as well as older versions. Returns an empty string
1425
+ * if nothing is found.
1426
+ * @access private
1427
+ * @return mixed
1428
+ */
1429
+ function ServerVar($varName) {
1430
+ global $HTTP_SERVER_VARS;
1431
+ global $HTTP_ENV_VARS;
1432
+
1433
+ if(!isset($_SERVER))
1434
+ {
1435
+ $_SERVER = $HTTP_SERVER_VARS;
1436
+ if(!isset($_SERVER["REMOTE_ADDR"]))
1437
+ $_SERVER = $HTTP_ENV_VARS; // must be Apache
1438
+ }
1439
+
1440
+ if(isset($_SERVER[$varName]))
1441
+ return $_SERVER[$varName];
1442
+ else
1443
+ return "";
1444
+ }
1445
+
1446
+ /**
1447
+ * Returns the server hostname or 'localhost.localdomain' if unknown.
1448
+ * @access private
1449
+ * @return string
1450
+ */
1451
+ function ServerHostname() {
1452
+ if ($this->Hostname != "")
1453
+ $result = $this->Hostname;
1454
+ elseif ($this->ServerVar('SERVER_NAME') != "")
1455
+ $result = $this->ServerVar('SERVER_NAME');
1456
+ else
1457
+ $result = "localhost.localdomain";
1458
+
1459
+ return $result;
1460
+ }
1461
+
1462
+ /**
1463
+ * Returns a message in the appropriate language.
1464
+ * @access private
1465
+ * @return string
1466
+ */
1467
+ function Lang($key) {
1468
+ if(count($this->language) < 1)
1469
+ $this->SetLanguage("en"); // set the default language
1470
+
1471
+ if(isset($this->language[$key]))
1472
+ return $this->language[$key];
1473
+ else
1474
+ return "Language string failed to load: " . $key;
1475
+ }
1476
+
1477
+ /**
1478
+ * Returns true if an error occurred.
1479
+ * @return bool
1480
+ */
1481
+ function IsError() {
1482
+ return ($this->error_count > 0);
1483
+ }
1484
+
1485
+ /**
1486
+ * Changes every end of line from CR or LF to CRLF.
1487
+ * @access private
1488
+ * @return string
1489
+ */
1490
+ function FixEOL($str) {
1491
+ $str = str_replace("\r\n", "\n", $str);
1492
+ $str = str_replace("\r", "\n", $str);
1493
+ $str = str_replace("\n", $this->LE, $str);
1494
+ return $str;
1495
+ }
1496
+
1497
+ /**
1498
+ * Adds a custom header.
1499
+ * @return void
1500
+ */
1501
+ function AddCustomHeader($custom_header) {
1502
+ $this->CustomHeader[] = explode(":", $custom_header, 2);
1503
+ }
1504
+ }
1505
+
1506
+ ?>
phpmailer/class.smtp.php ADDED
@@ -0,0 +1,1045 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ////////////////////////////////////////////////////
3
+ // SMTP - PHP SMTP class
4
+ //
5
+ // Version 1.02
6
+ //
7
+ // Define an SMTP class that can be used to connect
8
+ // and communicate with any SMTP server. It implements
9
+ // all the SMTP functions defined in RFC821 except TURN.
10
+ //
11
+ // Author: Chris Ryan
12
+ //
13
+ // License: LGPL, see LICENSE
14
+ ////////////////////////////////////////////////////
15
+
16
+ /**
17
+ * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
18
+ * commands except TURN which will always return a not implemented
19
+ * error. SMTP also provides some utility methods for sending mail
20
+ * to an SMTP server.
21
+ * @package PHPMailer
22
+ * @author Chris Ryan
23
+ */
24
+ class SMTP
25
+ {
26
+ /**
27
+ * SMTP server port
28
+ * @var int
29
+ */
30
+ var $SMTP_PORT = 25;
31
+
32
+ /**
33
+ * SMTP reply line ending
34
+ * @var string
35
+ */
36
+ var $CRLF = "\r\n";
37
+
38
+ /**
39
+ * Sets whether debugging is turned on
40
+ * @var bool
41
+ */
42
+ var $do_debug; # the level of debug to perform
43
+
44
+ /**#@+
45
+ * @access private
46
+ */
47
+ var $smtp_conn; # the socket to the server
48
+ var $error; # error if any on the last call
49
+ var $helo_rply; # the reply the server sent to us for HELO
50
+ /**#@-*/
51
+
52
+ /**
53
+ * Initialize the class so that the data is in a known state.
54
+ * @access public
55
+ * @return void
56
+ */
57
+ function SMTP() {
58
+ $this->smtp_conn = 0;
59
+ $this->error = null;
60
+ $this->helo_rply = null;
61
+
62
+ $this->do_debug = 0;
63
+ }
64
+
65
+ /*************************************************************
66
+ * CONNECTION FUNCTIONS *
67
+ ***********************************************************/
68
+
69
+ /**
70
+ * Connect to the server specified on the port specified.
71
+ * If the port is not specified use the default SMTP_PORT.
72
+ * If tval is specified then a connection will try and be
73
+ * established with the server for that number of seconds.
74
+ * If tval is not specified the default is 30 seconds to
75
+ * try on the connection.
76
+ *
77
+ * SMTP CODE SUCCESS: 220
78
+ * SMTP CODE FAILURE: 421
79
+ * @access public
80
+ * @return bool
81
+ */
82
+ function Connect($host,$port=0,$tval=30) {
83
+ # set the error val to null so there is no confusion
84
+ $this->error = null;
85
+
86
+ # make sure we are __not__ connected
87
+ if($this->connected()) {
88
+ # ok we are connected! what should we do?
89
+ # for now we will just give an error saying we
90
+ # are already connected
91
+ $this->error =
92
+ array("error" => "Already connected to a server");
93
+ return false;
94
+ }
95
+
96
+ if(empty($port)) {
97
+ $port = $this->SMTP_PORT;
98
+ }
99
+
100
+ #connect to the smtp server
101
+ $this->smtp_conn = fsockopen($host, # the host of the server
102
+ $port, # the port to use
103
+ $errno, # error number if any
104
+ $errstr, # error message if any
105
+ $tval); # give up after ? secs
106
+ # verify we connected properly
107
+ if(empty($this->smtp_conn)) {
108
+ $this->error = array("error" => "Failed to connect to server",
109
+ "errno" => $errno,
110
+ "errstr" => $errstr);
111
+ if($this->do_debug >= 1) {
112
+ echo "SMTP -> ERROR: " . $this->error["error"] .
113
+ ": $errstr ($errno)" . $this->CRLF;
114
+ }
115
+ return false;
116
+ }
117
+
118
+ # sometimes the SMTP server takes a little longer to respond
119
+ # so we will give it a longer timeout for the first read
120
+ // Windows still does not have support for this timeout function
121
+ if(substr(PHP_OS, 0, 3) != "WIN")
122
+ socket_set_timeout($this->smtp_conn, $tval, 0);
123
+
124
+ # get any announcement stuff
125
+ $announce = $this->get_lines();
126
+
127
+ # set the timeout of any socket functions at 1/10 of a second
128
+ //if(function_exists("socket_set_timeout"))
129
+ // socket_set_timeout($this->smtp_conn, 0, 100000);
130
+
131
+ if($this->do_debug >= 2) {
132
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
133
+ }
134
+
135
+ return true;
136
+ }
137
+
138
+ /**
139
+ * Performs SMTP authentication. Must be run after running the
140
+ * Hello() method. Returns true if successfully authenticated.
141
+ * @access public
142
+ * @return bool
143
+ */
144
+ function Authenticate($username, $password) {
145
+ // Start authentication
146
+ fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
147
+
148
+ $rply = $this->get_lines();
149
+ $code = substr($rply,0,3);
150
+
151
+ if($code != 334) {
152
+ $this->error =
153
+ array("error" => "AUTH not accepted from server",
154
+ "smtp_code" => $code,
155
+ "smtp_msg" => substr($rply,4));
156
+ if($this->do_debug >= 1) {
157
+ echo "SMTP -> ERROR: " . $this->error["error"] .
158
+ ": " . $rply . $this->CRLF;
159
+ }
160
+ return false;
161
+ }
162
+
163
+ // Send encoded username
164
+ fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
165
+
166
+ $rply = $this->get_lines();
167
+ $code = substr($rply,0,3);
168
+
169
+ if($code != 334) {
170
+ $this->error =
171
+ array("error" => "Username not accepted from server",
172
+ "smtp_code" => $code,
173
+ "smtp_msg" => substr($rply,4));
174
+ if($this->do_debug >= 1) {
175
+ echo "SMTP -> ERROR: " . $this->error["error"] .
176
+ ": " . $rply . $this->CRLF;
177
+ }
178
+ return false;
179
+ }
180
+
181
+ // Send encoded password
182
+ fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
183
+
184
+ $rply = $this->get_lines();
185
+ $code = substr($rply,0,3);
186
+
187
+ if($code != 235) {
188
+ $this->error =
189
+ array("error" => "Password not accepted from server",
190
+ "smtp_code" => $code,
191
+ "smtp_msg" => substr($rply,4));
192
+ if($this->do_debug >= 1) {
193
+ echo "SMTP -> ERROR: " . $this->error["error"] .
194
+ ": " . $rply . $this->CRLF;
195
+ }
196
+ return false;
197
+ }
198
+
199
+ return true;
200
+ }
201
+
202
+ /**
203
+ * Returns true if connected to a server otherwise false
204
+ * @access private
205
+ * @return bool
206
+ */
207
+ function Connected() {
208
+ if(!empty($this->smtp_conn)) {
209
+ $sock_status = socket_get_status($this->smtp_conn);
210
+ if($sock_status["eof"]) {
211
+ # hmm this is an odd situation... the socket is
212
+ # valid but we aren't connected anymore
213
+ if($this->do_debug >= 1) {
214
+ echo "SMTP -> NOTICE:" . $this->CRLF .
215
+ "EOF caught while checking if connected";
216
+ }
217
+ $this->Close();
218
+ return false;
219
+ }
220
+ return true; # everything looks good
221
+ }
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * Closes the socket and cleans up the state of the class.
227
+ * It is not considered good to use this function without
228
+ * first trying to use QUIT.
229
+ * @access public
230
+ * @return void
231
+ */
232
+ function Close() {
233
+ $this->error = null; # so there is no confusion
234
+ $this->helo_rply = null;
235
+ if(!empty($this->smtp_conn)) {
236
+ # close the connection and cleanup
237
+ fclose($this->smtp_conn);
238
+ $this->smtp_conn = 0;
239
+ }
240
+ }
241
+
242
+
243
+ /***************************************************************
244
+ * SMTP COMMANDS *
245
+ *************************************************************/
246
+
247
+ /**
248
+ * Issues a data command and sends the msg_data to the server
249
+ * finializing the mail transaction. $msg_data is the message
250
+ * that is to be send with the headers. Each header needs to be
251
+ * on a single line followed by a <CRLF> with the message headers
252
+ * and the message body being seperated by and additional <CRLF>.
253
+ *
254
+ * Implements rfc 821: DATA <CRLF>
255
+ *
256
+ * SMTP CODE INTERMEDIATE: 354
257
+ * [data]
258
+ * <CRLF>.<CRLF>
259
+ * SMTP CODE SUCCESS: 250
260
+ * SMTP CODE FAILURE: 552,554,451,452
261
+ * SMTP CODE FAILURE: 451,554
262
+ * SMTP CODE ERROR : 500,501,503,421
263
+ * @access public
264
+ * @return bool
265
+ */
266
+ function Data($msg_data) {
267
+ $this->error = null; # so no confusion is caused
268
+
269
+ if(!$this->connected()) {
270
+ $this->error = array(
271
+ "error" => "Called Data() without being connected");
272
+ return false;
273
+ }
274
+
275
+ fputs($this->smtp_conn,"DATA" . $this->CRLF);
276
+
277
+ $rply = $this->get_lines();
278
+ $code = substr($rply,0,3);
279
+
280
+ if($this->do_debug >= 2) {
281
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
282
+ }
283
+
284
+ if($code != 354) {
285
+ $this->error =
286
+ array("error" => "DATA command not accepted from server",
287
+ "smtp_code" => $code,
288
+ "smtp_msg" => substr($rply,4));
289
+ if($this->do_debug >= 1) {
290
+ echo "SMTP -> ERROR: " . $this->error["error"] .
291
+ ": " . $rply . $this->CRLF;
292
+ }
293
+ return false;
294
+ }
295
+
296
+ # the server is ready to accept data!
297
+ # according to rfc 821 we should not send more than 1000
298
+ # including the CRLF
299
+ # characters on a single line so we will break the data up
300
+ # into lines by \r and/or \n then if needed we will break
301
+ # each of those into smaller lines to fit within the limit.
302
+ # in addition we will be looking for lines that start with
303
+ # a period '.' and append and additional period '.' to that
304
+ # line. NOTE: this does not count towards are limit.
305
+
306
+ # normalize the line breaks so we know the explode works
307
+ $msg_data = str_replace("\r\n","\n",$msg_data);
308
+ $msg_data = str_replace("\r","\n",$msg_data);
309
+ $lines = explode("\n",$msg_data);
310
+
311
+ # we need to find a good way to determine is headers are
312
+ # in the msg_data or if it is a straight msg body
313
+ # currently I'm assuming rfc 822 definitions of msg headers
314
+ # and if the first field of the first line (':' sperated)
315
+ # does not contain a space then it _should_ be a header
316
+ # and we can process all lines before a blank "" line as
317
+ # headers.
318
+ $field = substr($lines[0],0,strpos($lines[0],":"));
319
+ $in_headers = false;
320
+ if(!empty($field) && !strstr($field," ")) {
321
+ $in_headers = true;
322
+ }
323
+
324
+ $max_line_length = 998; # used below; set here for ease in change
325
+
326
+ while(list(,$line) = @each($lines)) {
327
+ $lines_out = null;
328
+ if($line == "" && $in_headers) {
329
+ $in_headers = false;
330
+ }
331
+ # ok we need to break this line up into several
332
+ # smaller lines
333
+ while(strlen($line) > $max_line_length) {
334
+ $pos = strrpos(substr($line,0,$max_line_length)," ");
335
+
336
+ # Patch to fix DOS attack
337
+ if(!$pos) {
338
+ $pos = $max_line_length - 1;
339
+ }
340
+
341
+ $lines_out[] = substr($line,0,$pos);
342
+ $line = substr($line,$pos + 1);
343
+ # if we are processing headers we need to
344
+ # add a LWSP-char to the front of the new line
345
+ # rfc 822 on long msg headers
346
+ if($in_headers) {
347
+ $line = "\t" . $line;
348
+ }
349
+ }
350
+ $lines_out[] = $line;
351
+
352
+ # now send the lines to the server
353
+ while(list(,$line_out) = @each($lines_out)) {
354
+ if(strlen($line_out) > 0)
355
+ {
356
+ if(substr($line_out, 0, 1) == ".") {
357
+ $line_out = "." . $line_out;
358
+ }
359
+ }
360
+ fputs($this->smtp_conn,$line_out . $this->CRLF);
361
+ }
362
+ }
363
+
364
+ # ok all the message data has been sent so lets get this
365
+ # over with aleady
366
+ fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
367
+
368
+ $rply = $this->get_lines();
369
+ $code = substr($rply,0,3);
370
+
371
+ if($this->do_debug >= 2) {
372
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
373
+ }
374
+
375
+ if($code != 250) {
376
+ $this->error =
377
+ array("error" => "DATA not accepted from server",
378
+ "smtp_code" => $code,
379
+ "smtp_msg" => substr($rply,4));
380
+ if($this->do_debug >= 1) {
381
+ echo "SMTP -> ERROR: " . $this->error["error"] .
382
+ ": " . $rply . $this->CRLF;
383
+ }
384
+ return false;
385
+ }
386
+ return true;
387
+ }
388
+
389
+ /**
390
+ * Expand takes the name and asks the server to list all the
391
+ * people who are members of the _list_. Expand will return
392
+ * back and array of the result or false if an error occurs.
393
+ * Each value in the array returned has the format of:
394
+ * [ <full-name> <sp> ] <path>
395
+ * The definition of <path> is defined in rfc 821
396
+ *
397
+ * Implements rfc 821: EXPN <SP> <string> <CRLF>
398
+ *
399
+ * SMTP CODE SUCCESS: 250
400
+ * SMTP CODE FAILURE: 550
401
+ * SMTP CODE ERROR : 500,501,502,504,421
402
+ * @access public
403
+ * @return string array
404
+ */
405
+ function Expand($name) {
406
+ $this->error = null; # so no confusion is caused
407
+
408
+ if(!$this->connected()) {
409
+ $this->error = array(
410
+ "error" => "Called Expand() without being connected");
411
+ return false;
412
+ }
413
+
414
+ fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
415
+
416
+ $rply = $this->get_lines();
417
+ $code = substr($rply,0,3);
418
+
419
+ if($this->do_debug >= 2) {
420
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
421
+ }
422
+
423
+ if($code != 250) {
424
+ $this->error =
425
+ array("error" => "EXPN not accepted from server",
426
+ "smtp_code" => $code,
427
+ "smtp_msg" => substr($rply,4));
428
+ if($this->do_debug >= 1) {
429
+ echo "SMTP -> ERROR: " . $this->error["error"] .
430
+ ": " . $rply . $this->CRLF;
431
+ }
432
+ return false;
433
+ }
434
+
435
+ # parse the reply and place in our array to return to user
436
+ $entries = explode($this->CRLF,$rply);
437
+ while(list(,$l) = @each($entries)) {
438
+ $list[] = substr($l,4);
439
+ }
440
+
441
+ return $list;
442
+ }
443
+
444
+ /**
445
+ * Sends the HELO command to the smtp server.
446
+ * This makes sure that we and the server are in
447
+ * the same known state.
448
+ *
449
+ * Implements from rfc 821: HELO <SP> <domain> <CRLF>
450
+ *
451
+ * SMTP CODE SUCCESS: 250
452
+ * SMTP CODE ERROR : 500, 501, 504, 421
453
+ * @access public
454
+ * @return bool
455
+ */
456
+ function Hello($host="") {
457
+ $this->error = null; # so no confusion is caused
458
+
459
+ if(!$this->connected()) {
460
+ $this->error = array(
461
+ "error" => "Called Hello() without being connected");
462
+ return false;
463
+ }
464
+
465
+ # if a hostname for the HELO wasn't specified determine
466
+ # a suitable one to send
467
+ if(empty($host)) {
468
+ # we need to determine some sort of appopiate default
469
+ # to send to the server
470
+ $host = "localhost";
471
+ }
472
+
473
+ // Send extended hello first (RFC 2821)
474
+ if(!$this->SendHello("EHLO", $host))
475
+ {
476
+ if(!$this->SendHello("HELO", $host))
477
+ return false;
478
+ }
479
+
480
+ return true;
481
+ }
482
+
483
+ /**
484
+ * Sends a HELO/EHLO command.
485
+ * @access private
486
+ * @return bool
487
+ */
488
+ function SendHello($hello, $host) {
489
+ fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
490
+
491
+ $rply = $this->get_lines();
492
+ $code = substr($rply,0,3);
493
+
494
+ if($this->do_debug >= 2) {
495
+ echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
496
+ }
497
+
498
+ if($code != 250) {
499
+ $this->error =
500
+ array("error" => $hello . " not accepted from server",
501
+ "smtp_code" => $code,
502
+ "smtp_msg" => substr($rply,4));
503
+ if($this->do_debug >= 1) {
504
+ echo "SMTP -> ERROR: " . $this->error["error"] .
505
+ ": " . $rply . $this->CRLF;
506
+ }
507
+ return false;
508
+ }
509
+
510
+ $this->helo_rply = $rply;
511
+
512
+ return true;
513
+ }
514
+
515
+ /**
516
+ * Gets help information on the keyword specified. If the keyword
517
+ * is not specified then returns generic help, ussually contianing
518
+ * A list of keywords that help is available on. This function
519
+ * returns the results back to the user. It is up to the user to
520
+ * handle the returned data. If an error occurs then false is
521
+ * returned with $this->error set appropiately.
522
+ *
523
+ * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
524
+ *
525
+ * SMTP CODE SUCCESS: 211,214
526
+ * SMTP CODE ERROR : 500,501,502,504,421
527
+ * @access public
528
+ * @return string
529
+ */
530
+ function Help($keyword="") {
531
+ $this->error = null; # to avoid confusion
532
+
533
+ if(!$this->connected()) {
534
+ $this->error = array(
535
+ "error" => "Called Help() without being connected");
536
+ return false;
537
+ }
538
+
539
+ $extra = "";
540
+ if(!empty($keyword)) {
541
+ $extra = " " . $keyword;
542
+ }
543
+
544
+ fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
545
+
546
+ $rply = $this->get_lines();
547
+ $code = substr($rply,0,3);
548
+
549
+ if($this->do_debug >= 2) {
550
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
551
+ }
552
+
553
+ if($code != 211 && $code != 214) {
554
+ $this->error =
555
+ array("error" => "HELP not accepted from server",
556
+ "smtp_code" => $code,
557
+ "smtp_msg" => substr($rply,4));
558
+ if($this->do_debug >= 1) {
559
+ echo "SMTP -> ERROR: " . $this->error["error"] .
560
+ ": " . $rply . $this->CRLF;
561
+ }
562
+ return false;
563
+ }
564
+
565
+ return $rply;
566
+ }
567
+
568
+ /**
569
+ * Starts a mail transaction from the email address specified in
570
+ * $from. Returns true if successful or false otherwise. If True
571
+ * the mail transaction is started and then one or more Recipient
572
+ * commands may be called followed by a Data command.
573
+ *
574
+ * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
575
+ *
576
+ * SMTP CODE SUCCESS: 250
577
+ * SMTP CODE SUCCESS: 552,451,452
578
+ * SMTP CODE SUCCESS: 500,501,421
579
+ * @access public
580
+ * @return bool
581
+ */
582
+ function Mail($from) {
583
+ $this->error = null; # so no confusion is caused
584
+
585
+ if(!$this->connected()) {
586
+ $this->error = array(
587
+ "error" => "Called Mail() without being connected");
588
+ return false;
589
+ }
590
+
591
+ fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF);
592
+
593
+ $rply = $this->get_lines();
594
+ $code = substr($rply,0,3);
595
+
596
+ if($this->do_debug >= 2) {
597
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
598
+ }
599
+
600
+ if($code != 250) {
601
+ $this->error =
602
+ array("error" => "MAIL not accepted from server",
603
+ "smtp_code" => $code,
604
+ "smtp_msg" => substr($rply,4));
605
+ if($this->do_debug >= 1) {
606
+ echo "SMTP -> ERROR: " . $this->error["error"] .
607
+ ": " . $rply . $this->CRLF;
608
+ }
609
+ return false;
610
+ }
611
+ return true;
612
+ }
613
+
614
+ /**
615
+ * Sends the command NOOP to the SMTP server.
616
+ *
617
+ * Implements from rfc 821: NOOP <CRLF>
618
+ *
619
+ * SMTP CODE SUCCESS: 250
620
+ * SMTP CODE ERROR : 500, 421
621
+ * @access public
622
+ * @return bool
623
+ */
624
+ function Noop() {
625
+ $this->error = null; # so no confusion is caused
626
+
627
+ if(!$this->connected()) {
628
+ $this->error = array(
629
+ "error" => "Called Noop() without being connected");
630
+ return false;
631
+ }
632
+
633
+ fputs($this->smtp_conn,"NOOP" . $this->CRLF);
634
+
635
+ $rply = $this->get_lines();
636
+ $code = substr($rply,0,3);
637
+
638
+ if($this->do_debug >= 2) {
639
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
640
+ }
641
+
642
+ if($code != 250) {
643
+ $this->error =
644
+ array("error" => "NOOP not accepted from server",
645
+ "smtp_code" => $code,
646
+ "smtp_msg" => substr($rply,4));
647
+ if($this->do_debug >= 1) {
648
+ echo "SMTP -> ERROR: " . $this->error["error"] .
649
+ ": " . $rply . $this->CRLF;
650
+ }
651
+ return false;
652
+ }
653
+ return true;
654
+ }
655
+
656
+ /**
657
+ * Sends the quit command to the server and then closes the socket
658
+ * if there is no error or the $close_on_error argument is true.
659
+ *
660
+ * Implements from rfc 821: QUIT <CRLF>
661
+ *
662
+ * SMTP CODE SUCCESS: 221
663
+ * SMTP CODE ERROR : 500
664
+ * @access public
665
+ * @return bool
666
+ */
667
+ function Quit($close_on_error=true) {
668
+ $this->error = null; # so there is no confusion
669
+
670
+ if(!$this->connected()) {
671
+ $this->error = array(
672
+ "error" => "Called Quit() without being connected");
673
+ return false;
674
+ }
675
+
676
+ # send the quit command to the server
677
+ fputs($this->smtp_conn,"quit" . $this->CRLF);
678
+
679
+ # get any good-bye messages
680
+ $byemsg = $this->get_lines();
681
+
682
+ if($this->do_debug >= 2) {
683
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
684
+ }
685
+
686
+ $rval = true;
687
+ $e = null;
688
+
689
+ $code = substr($byemsg,0,3);
690
+ if($code != 221) {
691
+ # use e as a tmp var cause Close will overwrite $this->error
692
+ $e = array("error" => "SMTP server rejected quit command",
693
+ "smtp_code" => $code,
694
+ "smtp_rply" => substr($byemsg,4));
695
+ $rval = false;
696
+ if($this->do_debug >= 1) {
697
+ echo "SMTP -> ERROR: " . $e["error"] . ": " .
698
+ $byemsg . $this->CRLF;
699
+ }
700
+ }
701
+
702
+ if(empty($e) || $close_on_error) {
703
+ $this->Close();
704
+ }
705
+
706
+ return $rval;
707
+ }
708
+
709
+ /**
710
+ * Sends the command RCPT to the SMTP server with the TO: argument of $to.
711
+ * Returns true if the recipient was accepted false if it was rejected.
712
+ *
713
+ * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
714
+ *
715
+ * SMTP CODE SUCCESS: 250,251
716
+ * SMTP CODE FAILURE: 550,551,552,553,450,451,452
717
+ * SMTP CODE ERROR : 500,501,503,421
718
+ * @access public
719
+ * @return bool
720
+ */
721
+ function Recipient($to) {
722
+ $this->error = null; # so no confusion is caused
723
+
724
+ if(!$this->connected()) {
725
+ $this->error = array(
726
+ "error" => "Called Recipient() without being connected");
727
+ return false;
728
+ }
729
+
730
+ fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
731
+
732
+ $rply = $this->get_lines();
733
+ $code = substr($rply,0,3);
734
+
735
+ if($this->do_debug >= 2) {
736
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
737
+ }
738
+
739
+ if($code != 250 && $code != 251) {
740
+ $this->error =
741
+ array("error" => "RCPT not accepted from server",
742
+ "smtp_code" => $code,
743
+ "smtp_msg" => substr($rply,4));
744
+ if($this->do_debug >= 1) {
745
+ echo "SMTP -> ERROR: " . $this->error["error"] .
746
+ ": " . $rply . $this->CRLF;
747
+ }
748
+ return false;
749
+ }
750
+ return true;
751
+ }
752
+
753
+ /**
754
+ * Sends the RSET command to abort and transaction that is
755
+ * currently in progress. Returns true if successful false
756
+ * otherwise.
757
+ *
758
+ * Implements rfc 821: RSET <CRLF>
759
+ *
760
+ * SMTP CODE SUCCESS: 250
761
+ * SMTP CODE ERROR : 500,501,504,421
762
+ * @access public
763
+ * @return bool
764
+ */
765
+ function Reset() {
766
+ $this->error = null; # so no confusion is caused
767
+
768
+ if(!$this->connected()) {
769
+ $this->error = array(
770
+ "error" => "Called Reset() without being connected");
771
+ return false;
772
+ }
773
+
774
+ fputs($this->smtp_conn,"RSET" . $this->CRLF);
775
+
776
+ $rply = $this->get_lines();
777
+ $code = substr($rply,0,3);
778
+
779
+ if($this->do_debug >= 2) {
780
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
781
+ }
782
+
783
+ if($code != 250) {
784
+ $this->error =
785
+ array("error" => "RSET failed",
786
+ "smtp_code" => $code,
787
+ "smtp_msg" => substr($rply,4));
788
+ if($this->do_debug >= 1) {
789
+ echo "SMTP -> ERROR: " . $this->error["error"] .
790
+ ": " . $rply . $this->CRLF;
791
+ }
792
+ return false;
793
+ }
794
+
795
+ return true;
796
+ }
797
+
798
+ /**
799
+ * Starts a mail transaction from the email address specified in
800
+ * $from. Returns true if successful or false otherwise. If True
801
+ * the mail transaction is started and then one or more Recipient
802
+ * commands may be called followed by a Data command. This command
803
+ * will send the message to the users terminal if they are logged
804
+ * in.
805
+ *
806
+ * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
807
+ *
808
+ * SMTP CODE SUCCESS: 250
809
+ * SMTP CODE SUCCESS: 552,451,452
810
+ * SMTP CODE SUCCESS: 500,501,502,421
811
+ * @access public
812
+ * @return bool
813
+ */
814
+ function Send($from) {
815
+ $this->error = null; # so no confusion is caused
816
+
817
+ if(!$this->connected()) {
818
+ $this->error = array(
819
+ "error" => "Called Send() without being connected");
820
+ return false;
821
+ }
822
+
823
+ fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
824
+
825
+ $rply = $this->get_lines();
826
+ $code = substr($rply,0,3);
827
+
828
+ if($this->do_debug >= 2) {
829
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
830
+ }
831
+
832
+ if($code != 250) {
833
+ $this->error =
834
+ array("error" => "SEND not accepted from server",
835
+ "smtp_code" => $code,
836
+ "smtp_msg" => substr($rply,4));
837
+ if($this->do_debug >= 1) {
838
+ echo "SMTP -> ERROR: " . $this->error["error"] .
839
+ ": " . $rply . $this->CRLF;
840
+ }
841
+ return false;
842
+ }
843
+ return true;
844
+ }
845
+
846
+ /**
847
+ * Starts a mail transaction from the email address specified in
848
+ * $from. Returns true if successful or false otherwise. If True
849
+ * the mail transaction is started and then one or more Recipient
850
+ * commands may be called followed by a Data command. This command
851
+ * will send the message to the users terminal if they are logged
852
+ * in and send them an email.
853
+ *
854
+ * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
855
+ *
856
+ * SMTP CODE SUCCESS: 250
857
+ * SMTP CODE SUCCESS: 552,451,452
858
+ * SMTP CODE SUCCESS: 500,501,502,421
859
+ * @access public
860
+ * @return bool
861
+ */
862
+ function SendAndMail($from) {
863
+ $this->error = null; # so no confusion is caused
864
+
865
+ if(!$this->connected()) {
866
+ $this->error = array(
867
+ "error" => "Called SendAndMail() without being connected");
868
+ return false;
869
+ }
870
+
871
+ fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
872
+
873
+ $rply = $this->get_lines();
874
+ $code = substr($rply,0,3);
875
+
876
+ if($this->do_debug >= 2) {
877
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
878
+ }
879
+
880
+ if($code != 250) {
881
+ $this->error =
882
+ array("error" => "SAML not accepted from server",
883
+ "smtp_code" => $code,
884
+ "smtp_msg" => substr($rply,4));
885
+ if($this->do_debug >= 1) {
886
+ echo "SMTP -> ERROR: " . $this->error["error"] .
887
+ ": " . $rply . $this->CRLF;
888
+ }
889
+ return false;
890
+ }
891
+ return true;
892
+ }
893
+
894
+ /**
895
+ * Starts a mail transaction from the email address specified in
896
+ * $from. Returns true if successful or false otherwise. If True
897
+ * the mail transaction is started and then one or more Recipient
898
+ * commands may be called followed by a Data command. This command
899
+ * will send the message to the users terminal if they are logged
900
+ * in or mail it to them if they are not.
901
+ *
902
+ * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
903
+ *
904
+ * SMTP CODE SUCCESS: 250
905
+ * SMTP CODE SUCCESS: 552,451,452
906
+ * SMTP CODE SUCCESS: 500,501,502,421
907
+ * @access public
908
+ * @return bool
909
+ */
910
+ function SendOrMail($from) {
911
+ $this->error = null; # so no confusion is caused
912
+
913
+ if(!$this->connected()) {
914
+ $this->error = array(
915
+ "error" => "Called SendOrMail() without being connected");
916
+ return false;
917
+ }
918
+
919
+ fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
920
+
921
+ $rply = $this->get_lines();
922
+ $code = substr($rply,0,3);
923
+
924
+ if($this->do_debug >= 2) {
925
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
926
+ }
927
+
928
+ if($code != 250) {
929
+ $this->error =
930
+ array("error" => "SOML not accepted from server",
931
+ "smtp_code" => $code,
932
+ "smtp_msg" => substr($rply,4));
933
+ if($this->do_debug >= 1) {
934
+ echo "SMTP -> ERROR: " . $this->error["error"] .
935
+ ": " . $rply . $this->CRLF;
936
+ }
937
+ return false;
938
+ }
939
+ return true;
940
+ }
941
+
942
+ /**
943
+ * This is an optional command for SMTP that this class does not
944
+ * support. This method is here to make the RFC821 Definition
945
+ * complete for this class and __may__ be implimented in the future
946
+ *
947
+ * Implements from rfc 821: TURN <CRLF>
948
+ *
949
+ * SMTP CODE SUCCESS: 250
950
+ * SMTP CODE FAILURE: 502
951
+ * SMTP CODE ERROR : 500, 503
952
+ * @access public
953
+ * @return bool
954
+ */
955
+ function Turn() {
956
+ $this->error = array("error" => "This method, TURN, of the SMTP ".
957
+ "is not implemented");
958
+ if($this->do_debug >= 1) {
959
+ echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
960
+ }
961
+ return false;
962
+ }
963
+
964
+ /**
965
+ * Verifies that the name is recognized by the server.
966
+ * Returns false if the name could not be verified otherwise
967
+ * the response from the server is returned.
968
+ *
969
+ * Implements rfc 821: VRFY <SP> <string> <CRLF>
970
+ *
971
+ * SMTP CODE SUCCESS: 250,251
972
+ * SMTP CODE FAILURE: 550,551,553
973
+ * SMTP CODE ERROR : 500,501,502,421
974
+ * @access public
975
+ * @return int
976
+ */
977
+ function Verify($name) {
978
+ $this->error = null; # so no confusion is caused
979
+
980
+ if(!$this->connected()) {
981
+ $this->error = array(
982
+ "error" => "Called Verify() without being connected");
983
+ return false;
984
+ }
985
+
986
+ fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
987
+
988
+ $rply = $this->get_lines();
989
+ $code = substr($rply,0,3);
990
+
991
+ if($this->do_debug >= 2) {
992
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
993
+ }
994
+
995
+ if($code != 250 && $code != 251) {
996
+ $this->error =
997
+ array("error" => "VRFY failed on name '$name'",
998
+ "smtp_code" => $code,
999
+ "smtp_msg" => substr($rply,4));
1000
+ if($this->do_debug >= 1) {
1001
+ echo "SMTP -> ERROR: " . $this->error["error"] .
1002
+ ": " . $rply . $this->CRLF;
1003
+ }
1004
+ return false;
1005
+ }
1006
+ return $rply;
1007
+ }
1008
+
1009
+ /*******************************************************************
1010
+ * INTERNAL FUNCTIONS *
1011
+ ******************************************************************/
1012
+
1013
+ /**
1014
+ * Read in as many lines as possible
1015
+ * either before eof or socket timeout occurs on the operation.
1016
+ * With SMTP we can tell if we have more lines to read if the
1017
+ * 4th character is '-' symbol. If it is a space then we don't
1018
+ * need to read anything else.
1019
+ * @access private
1020
+ * @return string
1021
+ */
1022
+ function get_lines() {
1023
+ $data = "";
1024
+ while($str = fgets($this->smtp_conn,515)) {
1025
+ if($this->do_debug >= 4) {
1026
+ echo "SMTP -> get_lines(): \$data was \"$data\"" .
1027
+ $this->CRLF;
1028
+ echo "SMTP -> get_lines(): \$str is \"$str\"" .
1029
+ $this->CRLF;
1030
+ }
1031
+ $data .= $str;
1032
+ if($this->do_debug >= 4) {
1033
+ echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
1034
+ }
1035
+ # if the 4th character is a space then we are done reading
1036
+ # so just break the loop
1037
+ if(substr($str,3,1) == " ") { break; }
1038
+ }
1039
+ return $data;
1040
+ }
1041
+
1042
+ }
1043
+
1044
+
1045
+ ?>
phpmailer/dbem_phpmailer.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // phpmailer support
3
+ function dbem_send_mail($subject="no title",$body="No message specified", $receiver='') {
4
+
5
+ global $smtpsettings, $phpmailer, $cformsSettings;
6
+
7
+ if ( file_exists(dirname(__FILE__) . '/class.phpmailer.php') && !class_exists('PHPMailer') ) {
8
+ require_once(dirname(__FILE__) . '/class.phpmailer.php');
9
+ require_once(dirname(__FILE__) . '/class.smtp.php');
10
+ }
11
+
12
+
13
+
14
+ $mail = new PHPMailer();
15
+ $mail->ClearAllRecipients();
16
+ $mail->ClearAddresses();
17
+ $mail->ClearAttachments();
18
+ $mail->CharSet = 'utf-8';
19
+ $mail->SetLanguage('en', dirname(__FILE__).'/');
20
+
21
+ $mail->PluginDir = dirname(__FILE__).'/';
22
+ get_option('dbem_rsvp_mail_send_method') == 'qmail' ?
23
+ $mail->IsQmail() :
24
+ $mail->Mailer = get_option('dbem_rsvp_mail_send_method');
25
+ $mail->Host = get_option('dbem_smtp_host');
26
+ $mail->port = get_option('dbem_rsvp_mail_port');
27
+ if(get_option('dbem_rsvp_mail_SMTPAuth') == '1')
28
+ $mail->SMTPAuth = TRUE;
29
+ $mail->Username = get_option('dbem_smtp_username');
30
+ $mail->Password = get_option('dbem_smtp_password');
31
+ $mail->From = get_option('dbem_mail_sender_address');
32
+ //$mail->SMTPDebug = true;
33
+
34
+ $mail->FromName = get_option('dbem_mail_sender_name'); // This is the from name in the email, you can put anything you like here
35
+ $mail->Body = $body;
36
+ $mail->Subject = $subject;
37
+ $mail->AddAddress($receiver);
38
+
39
+ if(!$mail->Send()){
40
+ echo "Message was not sent<br/ >";
41
+ echo "Mailer Error: " . $mail->ErrorInfo;
42
+ // print_r($mailer);
43
+ } else {
44
+ // echo "Message has been sent";
45
+ }
46
+ }
47
+ ?>
phpmailer/language/phpmailer.lang-br.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Portuguese Version
5
+ * By Paulo Henrique Garcia - paulo@controllerweb.com.br
6
+ */
7
+
8
+ $PHPMAILER_LANG = array();
9
+ $PHPMAILER_LANG["provide_address"] = 'Voc� deve fornecer pelo menos um endere�o de destinat�rio de email.';
10
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer n�o suportado.';
11
+ $PHPMAILER_LANG["execute"] = 'N�o foi poss�vel executar: ';
12
+ $PHPMAILER_LANG["instantiate"] = 'N�o foi poss�vel instanciar a fun��o mail.';
13
+ $PHPMAILER_LANG["authenticate"] = 'Erro de SMTP: N�o foi poss�vel autenticar.';
14
+ $PHPMAILER_LANG["from_failed"] = 'Os endere�os de rementente a seguir falharam: ';
15
+ $PHPMAILER_LANG["recipients_failed"] = 'Erro de SMTP: Os endere�os de destinat�rio a seguir falharam: ';
16
+ $PHPMAILER_LANG["data_not_accepted"] = 'Erro de SMTP: Dados n�o aceitos.';
17
+ $PHPMAILER_LANG["connect_host"] = 'Erro de SMTP: N�o foi poss�vel conectar com o servidor SMTP.';
18
+ $PHPMAILER_LANG["file_access"] = 'N�o foi poss�vel acessar o arquivo: ';
19
+ $PHPMAILER_LANG["file_open"] = 'Erro de Arquivo: N�o foi poss�vel abrir o arquivo: ';
20
+ $PHPMAILER_LANG["encoding"] = 'Codifica��o desconhecida: ';
21
+ ?>
phpmailer/language/phpmailer.lang-ca.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Catalan Version
5
+ * By Ivan: web AT microstudi DOT com
6
+ */
7
+
8
+ $PHPMAILER_LANG = array();
9
+
10
+ $PHPMAILER_LANG["provide_address"] = 'S\'ha de proveir almenys una adre�a d\'email com a destinatari.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer no est� suportat';
12
+ $PHPMAILER_LANG["execute"] = 'No es pot executar: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'No s\'ha pogut crear una inst�ncia de la funci� Mail.';
14
+ $PHPMAILER_LANG["authenticate"] = 'Error SMTP: No s\'hapogut autenticar.';
15
+ $PHPMAILER_LANG["from_failed"] = 'La(s) seg�ent(s) adreces de remitent han fallat: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'Error SMTP: Els seg�ents destinataris han fallat: ';
17
+ $PHPMAILER_LANG["data_not_accepted"] = 'Error SMTP: Dades no acceptades.';
18
+ $PHPMAILER_LANG["connect_host"] = 'Error SMTP: No es pot connectar al servidor SMTP.';
19
+ $PHPMAILER_LANG["file_access"] = 'No es pot accedir a l\'arxiu: ';
20
+ $PHPMAILER_LANG["file_open"] = 'Error d\'Arxiu: No es pot obrir l\'arxiu: ';
21
+ $PHPMAILER_LANG["encoding"] = 'Codificaci� desconeguda: ';
22
+ ?>
phpmailer/language/phpmailer.lang-cz.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Czech Version
5
+ */
6
+
7
+ $PHPMAILER_LANG = array();
8
+
9
+ $PHPMAILER_LANG["provide_address"] = 'Mus�te zadat alespo� jednu ' .
10
+ 'emailovou adresu p��jemce.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailov� klient nen� podporov�n.';
12
+ $PHPMAILER_LANG["execute"] = 'Nelze prov�st: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'Nelze vytvo�it instanci emailov� funkce.';
14
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Error: Chyba autentikace.';
15
+ $PHPMAILER_LANG["from_failed"] = 'N�sleduj�c� adresa From je nespr�vn�: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: Adresy p��jemc� ' .
17
+ 'nejsou spr�vn� ' .
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data nebyla p�ijata';
19
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Error: Nelze nav�zat spojen� se ' .
20
+ ' SMTP serverem.';
21
+ $PHPMAILER_LANG["file_access"] = 'Soubor nenalezen: ';
22
+ $PHPMAILER_LANG["file_open"] = 'File Error: Nelze otev��t soubor pro �ten�: ';
23
+ $PHPMAILER_LANG["encoding"] = 'Nezn�m� k�dov�n�: ';
24
+ ?>
phpmailer/language/phpmailer.lang-de.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * German Version
5
+ */
6
+
7
+ $PHPMAILER_LANG = array();
8
+
9
+ $PHPMAILER_LANG["provide_address"] = 'Bitte geben Sie mindestens eine ' .
10
+ 'Empf&auml;nger Emailadresse an.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer wird nicht unterst&uuml;tzt.';
12
+ $PHPMAILER_LANG["execute"] = 'Konnte folgenden Befehl nicht ausf&uuml;hren: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'Mail Funktion konnte nicht initialisiert werden.';
14
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Fehler: Authentifizierung fehlgeschlagen.';
15
+ $PHPMAILER_LANG["from_failed"] = 'Die folgende Absenderadresse ist nicht korrekt: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Fehler: Die folgenden ' .
17
+ 'Empf&auml;nger sind nicht korrekt: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Fehler: Daten werden nicht akzeptiert.';
19
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Fehler: Konnte keine Verbindung zum SMTP-Host herstellen.';
20
+ $PHPMAILER_LANG["file_access"] = 'Zugriff auf folgende Datei fehlgeschlagen: ';
21
+ $PHPMAILER_LANG["file_open"] = 'Datei Fehler: konnte folgende Datei nicht &ouml;ffnen: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Unbekanntes Encoding-Format: ';
23
+ ?>
phpmailer/language/phpmailer.lang-dk.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Danish Version
5
+ * Author: Mikael Stokkebro <info@stokkebro.dk>
6
+ */
7
+
8
+ $PHPMAILER_LANG = array();
9
+
10
+ $PHPMAILER_LANG["provide_address"] = 'Du skal indtaste mindst en ' .
11
+ 'modtagers emailadresse.';
12
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer underst�ttes ikke.';
13
+ $PHPMAILER_LANG["execute"] = 'Kunne ikke k�re: ';
14
+ $PHPMAILER_LANG["instantiate"] = 'Kunne ikke initialisere email funktionen.';
15
+ $PHPMAILER_LANG["authenticate"] = 'SMTP fejl: Kunne ikke logge p�.';
16
+ $PHPMAILER_LANG["from_failed"] = 'F�lgende afsenderadresse er forkert: ';
17
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP fejl: F�lgende' .
18
+ 'modtagere er forkerte: ';
19
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP fejl: Data kunne ikke accepteres.';
20
+ $PHPMAILER_LANG["connect_host"] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.';
21
+ $PHPMAILER_LANG["file_access"] = 'Ingen adgang til fil: ';
22
+ $PHPMAILER_LANG["file_open"] = 'Fil fejl: Kunne ikke �bne filen: ';
23
+ $PHPMAILER_LANG["encoding"] = 'Ukendt encode-format: ';
24
+ ?>
phpmailer/language/phpmailer.lang-en.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * English Version
5
+ */
6
+
7
+ $PHPMAILER_LANG = array();
8
+
9
+ $PHPMAILER_LANG["provide_address"] = 'You must provide at least one ' .
10
+ 'recipient email address.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.';
12
+ $PHPMAILER_LANG["execute"] = 'Could not execute: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'Could not instantiate mail function.';
14
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Error: Could not authenticate.';
15
+ $PHPMAILER_LANG["from_failed"] = 'The following From address failed: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: The following ' .
17
+ 'recipients failed: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data not accepted.';
19
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Error: Could not connect to SMTP host.';
20
+ $PHPMAILER_LANG["file_access"] = 'Could not access file: ';
21
+ $PHPMAILER_LANG["file_open"] = 'File Error: Could not open file: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Unknown encoding: ';
23
+ ?>
phpmailer/language/phpmailer.lang-es.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Versi�n en espa�ol
5
+ */
6
+
7
+ $PHPMAILER_LANG = array();
8
+
9
+ $PHPMAILER_LANG["provide_address"] = 'Debe proveer al menos una ' .
10
+ 'direcci�n de email como destinatario.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer no est� soportado.';
12
+ $PHPMAILER_LANG["execute"] = 'No puedo ejecutar: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'No pude crear una instancia de la funci�n Mail.';
14
+ $PHPMAILER_LANG["authenticate"] = 'Error SMTP: No se pudo autentificar.';
15
+ $PHPMAILER_LANG["from_failed"] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'Error SMTP: Los siguientes ' .
17
+ 'destinatarios fallaron: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'Error SMTP: Datos no aceptados.';
19
+ $PHPMAILER_LANG["connect_host"] = 'Error SMTP: No puedo conectar al servidor SMTP.';
20
+ $PHPMAILER_LANG["file_access"] = 'No puedo acceder al archivo: ';
21
+ $PHPMAILER_LANG["file_open"] = 'Error de Archivo: No puede abrir el archivo: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Codificaci�n desconocida: ';
23
+ ?>
phpmailer/language/phpmailer.lang-fi.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Finnish Version
5
+ * By Jyry Kuukanen
6
+ */
7
+
8
+ $PHPMAILER_LANG = array();
9
+
10
+ $PHPMAILER_LANG["provide_address"] = 'Aseta v&auml;hint&auml;&auml;n yksi vastaanottajan ' .
11
+ 's&auml;hk&ouml;postiosoite.';
12
+ $PHPMAILER_LANG["mailer_not_supported"] = 'postiv&auml;litintyyppi&auml; ei tueta.';
13
+ $PHPMAILER_LANG["execute"] = 'Suoritus ep&auml;onnistui: ';
14
+ $PHPMAILER_LANG["instantiate"] = 'mail-funktion luonti ep&auml;onnistui.';
15
+ $PHPMAILER_LANG["authenticate"] = 'SMTP-virhe: k&auml;ytt&auml;j&auml;tunnistus ep&auml;onnistui.';
16
+ $PHPMAILER_LANG["from_failed"] = 'Seuraava l&auml;hett&auml;j&auml;n osoite on virheellinen: ';
17
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP-virhe: data on virheellinen.';
19
+ $PHPMAILER_LANG["connect_host"] = 'SMTP-virhe: yhteys palvelimeen ei onnistu.';
20
+ $PHPMAILER_LANG["file_access"] = 'Seuraavaan tiedostoon ei ole oikeuksia: ';
21
+ $PHPMAILER_LANG["file_open"] = 'Tiedostovirhe: Ei voida avata tiedostoa: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Tuntematon koodaustyyppi: ';
23
+ ?>
phpmailer/language/phpmailer.lang-fo.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Faroese Version [language of the Faroe Islands, a Danish dominion]
5
+ * This file created: 11-06-2004
6
+ * Supplied by D�vur S�rensen [www.profo-webdesign.dk]
7
+ */
8
+
9
+ $PHPMAILER_LANG = array();
10
+
11
+ $PHPMAILER_LANG["provide_address"] = 'T� skal uppgeva minst ' .
12
+ 'm�ttakara-emailadressu(r).';
13
+ $PHPMAILER_LANG["mailer_not_supported"] = ' er ikki supportera�.';
14
+ $PHPMAILER_LANG["execute"] = 'Kundi ikki �tf�ra: ';
15
+ $PHPMAILER_LANG["instantiate"] = 'Kuni ikki instantiera mail funkti�n.';
16
+ $PHPMAILER_LANG["authenticate"] = 'SMTP feilur: Kundi ikki g��kenna.';
17
+ $PHPMAILER_LANG["from_failed"] = 'fylgjandi Fr�/From adressa miseydna�ist: ';
18
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Feilur: Fylgjandi ' .
19
+ 'm�ttakarar miseydna�ust: ';
20
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP feilur: Data ikki g��kent.';
21
+ $PHPMAILER_LANG["connect_host"] = 'SMTP feilur: Kundi ikki kn�ta samband vi� SMTP vert.';
22
+ $PHPMAILER_LANG["file_access"] = 'Kundi ikki tilganga f�lu: ';
23
+ $PHPMAILER_LANG["file_open"] = 'F�lu feilur: Kundi ikki opna f�lu: ';
24
+ $PHPMAILER_LANG["encoding"] = '�kend encoding: ';
25
+ ?>
phpmailer/language/phpmailer.lang-fr.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * French Version
5
+ * bruno@ioda-net.ch 09.08.2003
6
+ */
7
+
8
+ $PHPMAILER_LANG = array();
9
+
10
+ $PHPMAILER_LANG["provide_address"] = 'Vous devez fournir au moins ' .
11
+ 'une adresse de destinataire.';
12
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer non support�.';
13
+ $PHPMAILER_LANG["execute"] = 'Ne peut pas lancer l\'ex�cution: ';
14
+ $PHPMAILER_LANG["instantiate"] = 'Impossible d\'instancier la fonction mail.';
15
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Erreur: Echec de l\'authentification.';
16
+ $PHPMAILER_LANG["from_failed"] = 'L\'adresse From suivante a �chou� : ';
17
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Erreur: Les destinataires ' .
18
+ 'suivants sont en erreur : ';
19
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Erreur: Data non accept�e.';
20
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Erreur: Impossible de connecter le serveur SMTP .';
21
+ $PHPMAILER_LANG["file_access"] = 'N\'arrive pas � acc�der au fichier: ';
22
+ $PHPMAILER_LANG["file_open"] = 'Erreur Fichier: ouverture impossible: ';
23
+ $PHPMAILER_LANG["encoding"] = 'Encodage inconnu: ';
24
+ ?>
phpmailer/language/phpmailer.lang-hu.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Hungarian Version
5
+ */
6
+
7
+ $PHPMAILER_LANG = array();
8
+
9
+ $PHPMAILER_LANG["provide_address"] = 'Meg kell adnod legal�bb egy ' .
10
+ 'c�mzett email c�met.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' levelez� nem t�mogatott.';
12
+ $PHPMAILER_LANG["execute"] = 'Nem tudtam v�grehajtani: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'Nem siker�lt p�ld�nyos�tani a mail funkci�t.';
14
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Hiba: Sikertelen autentik�ci�.';
15
+ $PHPMAILER_LANG["from_failed"] = 'Az al�bbi Felad� c�m hib�s: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Hiba: Az al�bbi ' .
17
+ 'c�mzettek hib�sak: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Hiba: Nem elfogadhat� adat.';
19
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Hiba: Nem tudtam csatlakozni az SMTP host-hoz.';
20
+ $PHPMAILER_LANG["file_access"] = 'Nem siker�lt el�rni a k�vetkez� f�jlt: ';
21
+ $PHPMAILER_LANG["file_open"] = 'F�jl Hiba: Nem siker�lt megnyitni a k�vetkez� f�jlt: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Ismeretlen k�dol�s: ';
23
+ ?>
phpmailer/language/phpmailer.lang-it.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Italian version
5
+ * @package PHPMailer
6
+ * @author Ilias Bartolini <brain79@inwind.it>
7
+ */
8
+
9
+ $PHPMAILER_LANG = array();
10
+
11
+ $PHPMAILER_LANG["provide_address"] = 'Deve essere fornito almeno un'.
12
+ ' indirizzo ricevente';
13
+ $PHPMAILER_LANG["mailer_not_supported"] = 'Mailer non supportato';
14
+ $PHPMAILER_LANG["execute"] = "Impossibile eseguire l'operazione: ";
15
+ $PHPMAILER_LANG["instantiate"] = 'Impossibile istanziare la funzione mail';
16
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Error: Impossibile autenticarsi.';
17
+ $PHPMAILER_LANG["from_failed"] = 'I seguenti indirizzi mittenti hanno'.
18
+ ' generato errore: ';
19
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: I seguenti indirizzi'.
20
+ 'destinatari hanno generato errore: ';
21
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data non accettati dal'.
22
+ 'server.';
23
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Error: Impossibile connettersi'.
24
+ ' all\'host SMTP.';
25
+ $PHPMAILER_LANG["file_access"] = 'Impossibile accedere al file: ';
26
+ $PHPMAILER_LANG["file_open"] = 'File Error: Impossibile aprire il file: ';
27
+ $PHPMAILER_LANG["encoding"] = 'Encoding set dei caratteri sconosciuto: ';
28
+ ?>
phpmailer/language/phpmailer.lang-ja.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Japanese Version
5
+ * By Mitsuhiro Yoshida - http://mitstek.com/
6
+ * This file is written in EUC-JP.
7
+ */
8
+
9
+ $PHPMAILER_LANG = array();
10
+
11
+ $PHPMAILER_LANG["provide_address"] = '���ʤ��Ȥ�1�ĥ᡼�륢�ɥ쥹��' .
12
+ '���ꤹ��ɬ�פ�����ޤ���';
13
+ $PHPMAILER_LANG["mailer_not_supported"] = ' �᡼�顼�����ݡ��Ȥ���Ƥ��ޤ���';
14
+ $PHPMAILER_LANG["execute"] = '�¹ԤǤ��ޤ���Ǥ���: ';
15
+ $PHPMAILER_LANG["instantiate"] = '�᡼��ؿ��������ư��ޤ���Ǥ�����';
16
+ $PHPMAILER_LANG["authenticate"] = 'SMTP���顼: ǧ�ڤǤ��ޤ���Ǥ�����';
17
+ $PHPMAILER_LANG["from_failed"] = '����From���ɥ쥹�˴ְ㤤������ޤ�: ';
18
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP���顼: ���μ����ԥ��ɥ쥹�� ' .
19
+ '�ְ㤤������ޤ�: ';
20
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP���顼: �ǡ����������դ����ޤ���Ǥ�����';
21
+ $PHPMAILER_LANG["connect_host"] = 'SMTP���顼: SMTP�ۥ��Ȥ���³�Ǥ��ޤ���Ǥ�����';
22
+ $PHPMAILER_LANG["file_access"] = '�ե�����˥��������Ǥ��ޤ���: ';
23
+ $PHPMAILER_LANG["file_open"] = '�ե����륨�顼: �ե�����򳫤��ޤ���: ';
24
+ $PHPMAILER_LANG["encoding"] = '�����ʥ��󥳡��ǥ���: ';
25
+ ?>
phpmailer/language/phpmailer.lang-nl.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Dutch Version
5
+ */
6
+
7
+ $PHPMAILER_LANG = array();
8
+
9
+ $PHPMAILER_LANG["provide_address"] = 'Er moet tenmiste &eacute;&eacute;n ' .
10
+ 'ontvanger emailadres opgegeven worden.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer wordt niet ondersteund.';
12
+ $PHPMAILER_LANG["execute"] = 'Kon niet uitvoeren: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'Kon mail functie niet initialiseren.';
14
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Fout: authenticatie mislukt.';
15
+ $PHPMAILER_LANG["from_failed"] = 'De volgende afzender adressen zijn mislukt: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Fout: De volgende ' .
17
+ 'ontvangers zijn mislukt: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Fout: Data niet geaccepteerd.';
19
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Fout: Kon niet verbinden met SMTP host.';
20
+ $PHPMAILER_LANG["file_access"] = 'Kreeg geen toegang tot bestand: ';
21
+ $PHPMAILER_LANG["file_open"] = 'Bestandsfout: Kon bestand niet openen: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Onbekende codering: ';
23
+ ?>
phpmailer/language/phpmailer.lang-no.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Norwegian Version
5
+ */
6
+
7
+ $PHPMAILER_LANG = array();
8
+
9
+ $PHPMAILER_LANG["provide_address"] = 'Du m� ha med minst en' .
10
+ 'mottager adresse.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer er ikke supportert.';
12
+ $PHPMAILER_LANG["execute"] = 'Kunne ikke utf�re: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'Kunne ikke instantiate mail funksjonen.';
14
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Feil: Kunne ikke authentisere.';
15
+ $PHPMAILER_LANG["from_failed"] = 'F�lgende Fra feilet: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Feil: F�lgende' .
17
+ 'mottagere feilet: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Feil: Data ble ikke akseptert.';
19
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Feil: Kunne ikke koble til SMTP host.';
20
+ $PHPMAILER_LANG["file_access"] = 'Kunne ikke f� tilgang til filen: ';
21
+ $PHPMAILER_LANG["file_open"] = 'Fil feil: Kunne ikke �pne filen: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Ukjent encoding: ';
23
+ ?>
phpmailer/language/phpmailer.lang-pl.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Polish Version, encoding: windows-1250
5
+ * translated from english lang file ver. 1.72
6
+ */
7
+
8
+ $PHPMAILER_LANG = array();
9
+
10
+ $PHPMAILER_LANG["provide_address"] = 'Nale�y poda� prawid�owy adres email Odbiorcy.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = 'Wybrana metoda wysy�ki wiadomo�ci nie jest obs�ugiwana.';
12
+ $PHPMAILER_LANG["execute"] = 'Nie mo�na uruchomi�: ';
13
+ $PHPMAILER_LANG["instantiate"] = 'Nie mo�na wywo�a� funkcji mail(). Sprawd� konfiguracj� serwera.';
14
+ $PHPMAILER_LANG["authenticate"] = 'B��d SMTP: Nie mo�na przeprowadzi� autentykacji.';
15
+ $PHPMAILER_LANG["from_failed"] = 'Nast�puj�cy adres Nadawcy jest jest nieprawid�owy: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'B��d SMTP: Nast�puj�cy ' .
17
+ 'odbiorcy s� nieprawid�owi: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'B��d SMTP: Dane nie zosta�y przyj�te.';
19
+ $PHPMAILER_LANG["connect_host"] = 'B��d SMTP: Nie mo�na po��czy� si� z wybranym hostem.';
20
+ $PHPMAILER_LANG["file_access"] = 'Brak dost�pu do pliku: ';
21
+ $PHPMAILER_LANG["file_open"] = 'Nie mo�na otworzy� pliku: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Nieznany spos�b kodowania znak�w: ';
23
+
24
+ ?>
phpmailer/language/phpmailer.lang-ro.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Romanian Version
5
+ * @package PHPMailer
6
+ * @author Catalin Constantin <catalin@dazoot.ro>
7
+ */
8
+
9
+ $PHPMAILER_LANG = array();
10
+
11
+ $PHPMAILER_LANG["provide_address"] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).';
12
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer nu este suportat.';
13
+ $PHPMAILER_LANG["execute"] = 'Nu pot executa: ';
14
+ $PHPMAILER_LANG["instantiate"] = 'Nu am putut instantia functia mail.';
15
+ $PHPMAILER_LANG["authenticate"] = 'Eroare SMTP: Nu a functionat autentificarea.';
16
+ $PHPMAILER_LANG["from_failed"] = 'Urmatoarele adrese From au dat eroare: ';
17
+ $PHPMAILER_LANG["recipients_failed"] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'Eroare SMTP: Continutul mailului nu a fost acceptat.';
19
+ $PHPMAILER_LANG["connect_host"] = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.';
20
+ $PHPMAILER_LANG["file_access"] = 'Nu pot accesa fisierul: ';
21
+ $PHPMAILER_LANG["file_open"] = 'Eroare de fisier: Nu pot deschide fisierul: ';
22
+ $PHPMAILER_LANG["encoding"] = 'Encodare necunoscuta: ';
23
+ ?>
phpmailer/language/phpmailer.lang-ru.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Russian Version
5
+ */
6
+
7
+ $PHPMAILER_LANG = array();
8
+
9
+ $PHPMAILER_LANG["provide_address"] = '���������� ������� ������� ���� Email' .
10
+ '����������.';
11
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer �� ��������������.';
12
+ $PHPMAILER_LANG["execute"] = '���������� ��������� ��� �������: ';
13
+ $PHPMAILER_LANG["instantiate"] = '��������� ������ ��� ������������� Mail �������.';
14
+ $PHPMAILER_LANG["authenticate"] = 'SMTP ������: ������ �����������.';
15
+ $PHPMAILER_LANG["from_failed"] = '�������� ����� �����������: ';
16
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP ������: ��������� ' .
17
+ '������ ����������� �������: ';
18
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP ������: ������ �� ���� �������.';
19
+ $PHPMAILER_LANG["connect_host"] = 'SMTP ������: SMTP-Host ����������.';
20
+ $PHPMAILER_LANG["file_access"] = '� ������� � ���������� ����� ���� ��������: ';
21
+ $PHPMAILER_LANG["file_open"] = '�� ���� ������� ����: ';
22
+ $PHPMAILER_LANG["encoding"] = '����������� ������ ���������: ';
23
+ ?>
phpmailer/language/phpmailer.lang-se.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer language file.
4
+ * Swedish Version
5
+ * Author: Johan Linn�r <johan@linner.biz>
6
+ */
7
+
8
+ $PHPMAILER_LANG = array();
9
+
10
+ $PHPMAILER_LANG["provide_address"] = 'Du m�ste ange minst en ' .
11
+ 'mottagares e-postadress.';
12
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailer st�ds inte.';
13
+ $PHPMAILER_LANG["execute"] = 'Kunde inte k�ra: ';
14
+ $PHPMAILER_LANG["instantiate"] = 'Kunde inte initiera e-postfunktion.';
15
+ $PHPMAILER_LANG["authenticate"] = 'SMTP fel: Kunde inte autentisera.';
16
+ $PHPMAILER_LANG["from_failed"] = 'F�ljande avs�ndaradress �r felaktig: ';
17
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP fel: F�ljande ' .
18
+ 'mottagare �r felaktig: ';
19
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP fel: Data accepterades inte.';
20
+ $PHPMAILER_LANG["connect_host"] = 'SMTP fel: Kunde inte ansluta till SMTP-server.';
21
+ $PHPMAILER_LANG["file_access"] = 'Ingen �tkomst till fil: ';
22
+ $PHPMAILER_LANG["file_open"] = 'Fil fel: Kunde inte �ppna fil: ';
23
+ $PHPMAILER_LANG["encoding"] = 'Ok�nt encode-format: ';
24
+ ?>
phpmailer/language/phpmailer.lang-tr.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer dil dosyas�.
4
+ * T�rk�e Versiyonu
5
+ * �ZYAZILIM - El�in �zel - Can Y�lmaz - Mehmet Benlio�lu
6
+ */
7
+
8
+ $PHPMAILER_LANG = array();
9
+
10
+ $PHPMAILER_LANG["provide_address"] = 'En az bir tane mail adresi belirtmek zorundas�n�z ' .
11
+ 'al�c�n�n email adresi.';
12
+ $PHPMAILER_LANG["mailer_not_supported"] = ' mailler desteklenmemektedir.';
13
+ $PHPMAILER_LANG["execute"] = '�al��t�r�lam�yor: ';
14
+ $PHPMAILER_LANG["instantiate"] = '�rnek mail fonksiyonu yarat�lamad�.';
15
+ $PHPMAILER_LANG["authenticate"] = 'SMTP Hatas�: Do�rulanam�yor.';
16
+ $PHPMAILER_LANG["from_failed"] = 'Ba�ar�s�z olan g�nderici adresi: ';
17
+ $PHPMAILER_LANG["recipients_failed"] = 'SMTP Hatas�: ' .
18
+ 'al�c�lara ula�mad�: ';
19
+ $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Hatas�: Veri kabul edilmedi.';
20
+ $PHPMAILER_LANG["connect_host"] = 'SMTP Hatas�: SMTP hosta ba�lan�lam�yor.';
21
+ $PHPMAILER_LANG["file_access"] = 'Dosyaya eri�ilemiyor: ';
22
+ $PHPMAILER_LANG["file_open"] = 'Dosya Hatas�: Dosya a��lam�yor: ';
23
+ $PHPMAILER_LANG["encoding"] = 'Bilinmeyen �ifreleme: ';
24
+
25
+ ?>
readme.txt CHANGED
@@ -1,16 +1,16 @@
1
  === Events Manager ===
2
  Contributors: nutsmuggler
3
- Tags: events
4
  Requires at least: 2.5.1
5
- Tested up to: 2.6
6
- Stable tag: 1.0.1
7
  Donate link: http://davidebenini.it/wordpress-plugins/
8
 
9
- Manage events and display them in your blog. Includes lists, calendar, Google map integration and sidebar widgets.
10
 
11
  == Description ==
12
 
13
- Events Manager is a plugin to manage events such as music gigs, art expositions, or even job meetings. Events Manager inserts an *Events* page in the *Manage* menu of Wordpress Administration, to let you insert, modify and delete events. You can describe events specifying their date and location, and also add a few notes. You can then add events list, calendars and description to your blog using a sidebar widget; if you're web designer you can simply employ the template tags provided by Events Manager.
14
 
15
  Events Manager integrates with Google Maps; thanks the geocoding, Events Manager can find the location of your events, and accordingly display a map. To enable Google Maps integration, you need a Google maps API key, which you can obtain freely at the [Google Maps API Signup Page](http://code.google.com/apis/maps/signup.html).
16
 
@@ -18,105 +18,36 @@ Events Manager provides also a RSS feed, to keep your subscribers updated about
18
 
19
  Events manager is fully customisable; you can customise the amount of data displayed and their format in events lists, pages and in the RSS feed. You can choose to show or hide the events page, and change its title.
20
 
21
- Events Manager is fully localisable. I have added an Italian localisation, and I'd welcome any translator willing to localise this plugin into his mother tongue.
22
 
23
  == Installation ==
24
 
25
-
26
  1. Upload the `events-manager` folder to the `/wp-content/plugins/` directory
27
  2. Activate the plugin through the 'Plugins' menu in WordPress
28
  3. Add events list or calendars following the instructions in the Usage section.
29
 
30
- == Usage ==
31
-
32
- After the installation, Events Manager adds two pages to your Wordpress Administration.
33
-
34
- * Manage/Events is the page where you add, delete or modify events. You will see three pre-installed events in this page. Delete them and add your events own events. Choose between the visualisation of present/past/all events.
35
- * Settings/Events Manager is where you set the Events Manager options. The page fields contain a description of their use; for more information, see *Formatting the events*.
36
-
37
- Events list and calendars can be added to your blogs through widgets or template tags.
38
 
39
- = Widgets =
 
 
 
40
 
41
- Add the Events List or Events Calendar widgets to any of your sidebar. To do so, your theme must be [widget-ready](http://automattic.com/code/widgets/). You can change the title of both widgets. Moreover, you can adjust the formats of the events of Events List according to your need; see *Formatting Events*.
42
-
43
 
44
- = Template tags =
45
-
46
- If you're into theming, you should probably use the template tags provided by Events Manager. Here's a comprehensive list.
47
-
48
- `<?php dbem_get_events_list(limit, scope, order, format,display); ?>`
49
-
50
- Prints or returns a list of the events. Accepts up to five optional parameters:
51
 
52
- * `limit` indicates the maximum number of events to display. Default is 3.
53
- * `scope` indicates lets you choose whether to show `future`, `past` or `all` events. Default is `future`.
54
- * `order` indicates indicates the order of the events. Choose between ASC (ascendant, default) and DESC (descendant).
55
- * `format`: the format of each item. If not specified, Events Manager will use the format specified in the *Default event list format* setting of the setting page.
56
- * `display` indicates whether the list should be printed (`true`) or just returned (`false`). This option should be ignored, unless you know what you are doing.
57
 
58
- Example: `dbem_get_events_list(5, "all", "DESC")` will print a list of the latest 5 events, including past ones, in a descendant order.
 
 
 
 
 
59
 
 
60
 
61
- `<?php dbem_get_calendar(); ?>`
62
-
63
- Prints the current month calendar, highlighting any event and linking to it. Accepts no parameters.
64
-
65
- `<?php dbem_get_events_page(justurl) ?>`
66
-
67
- Prints a link to the events page. If you set the optional `justurl` property to `true`, the function only prints the URL of the events page.
68
-
69
- `<?php dbem_rss_link(justurl) ?>`
70
- Prints a the link to the events RSS. If you set the optional `justurl` property to `true`, the function only prints the RSS URL.
71
-
72
- = Conditional template tags =
73
-
74
- These tags return true or false, and are useful to structure your themes.
75
-
76
- `<?php dbem_are_events_available(scope) ?>`
77
- Returns true if events are available in `scope`. The default value of `scope` is future.
78
-
79
- `<?php dbem_is_events_page() ?>`
80
- Returns true if the page loaded corresponds to the events page.
81
-
82
- `<?php dbem_is_single_event_page() ?>`
83
- Returns true if the page loaded corresponds to a single event page.
84
-
85
- `<?php dbem_is_multiple_events_page() ?>`
86
- Returns true if the page loaded corresponds the multiple events page.
87
-
88
- == Formatting the events ==
89
-
90
- Events Manager lets you choose the format of the events displayed in your list and pages. Navigate to Settings/Events Manager and set the format of events in list; the format of the list widget is set directly in the widget settings.
91
-
92
- The syntax of events format is quite simple. Basically, just write your html code in the usual way. Then you can add a number of placeholders corresponding to the data of the event. They are:
93
-
94
- * `#_NAME` displays the name of the event
95
- * `#_VENUE` displays the venue (theatre, pub, etc)
96
- * `#_ADDRESS` displays the address
97
- * `#_TOWN` displays the town
98
- * `#_LINKEDNAME` displays the event name with a link to the event page
99
- * `#_URL` simply prints the events URL. You can use this placeholder to build your own customised links
100
-
101
-
102
- To add temporal information about the events, use [PHP syntax format characters](http://www.php.net/manual/en/function.date.php) with a # before them. For example:
103
-
104
- * `#d` displays a Day of the month, with 2 digits with leading zeros
105
- * `#m` displas short textual representation of a month, three letters (*jan* through *dec*)
106
- * etc
107
-
108
- If you have enabled the Google Map integration, you can use #_MAP to display a map; this placeholder, of course, shouldn't generally be used for list items.
109
-
110
- == Google Maps Integration ==
111
-
112
- To use Google Maps with Events Manager, you need a Goggle Map API key. Don't worry, it's free, you can get one [here](http://code.google.com/apis/maps/signup.html).
113
-
114
- Once you have got you API key, go to *Settings/Events Manager*, insert you key in the *Google Maps API Key* field and set *Enable Google Maps integration?* to *Yes*.
115
-
116
- Now you just need to put a the #_MAP placeholder in the *Default single event format*, and your map will show in the page dedicated to the event.
117
-
118
- To resize the map, simply tweak the `#event-map` in your css.
119
-
120
  == Frequently Asked Questions ==
121
 
122
  = I enabled the Google Maps integration, but instead of the map there is a green background. What should I do? =
@@ -170,15 +101,6 @@ At this stage, Events Manager is only available in English and Italian. Yet, the
170
  2. The events management page.
171
  3. The Events Manager Options page.
172
 
173
- == Future features ==
174
-
175
- This is a short list of the features that I intend to implement:
176
-
177
- * Javascript datepicker
178
- * End dates; events will have a beginning and (optionally) an ending
179
-
180
- I have other ideas in the pipeline, but I'll stick to this ones and implement them first.
181
-
182
  == Change Log ==
183
 
184
  1.0b1
@@ -210,3 +132,12 @@ Fixed CSS bug: enclosed list in Events page in "ul" elements, as it should be.
210
  Fixed a bug loaded the Google Maps Api when deleting events.
211
  Fixed a bug that prevented validation in the default widget list item format.
212
 
 
 
 
 
 
 
 
 
 
1
  === Events Manager ===
2
  Contributors: nutsmuggler
3
+ Tags: events, manager, calendar, gigs, concert, maps, geotagging
4
  Requires at least: 2.5.1
5
+ Tested up to: 2.7
6
+ Stable tag: 2.0b1
7
  Donate link: http://davidebenini.it/wordpress-plugins/
8
 
9
+ Manage events and display them in your blog. Includes recurring events, location management, calendar, Google map integration, RSVP.
10
 
11
  == Description ==
12
 
13
+ Events Manager 2.0 is a full-featured event management solution for Wordpress. Events Manager supports recurring events, venues data, RSVP and maps. With Events Manager you can plan and publish your tour, or let people reserve spaces for your weekly meetings. You can then add events list, calendars and description to your blog using a sidebar widget or shortcodes; if youre web designer you can simply employ the template tags provided by Events Manager.
14
 
15
  Events Manager integrates with Google Maps; thanks the geocoding, Events Manager can find the location of your events, and accordingly display a map. To enable Google Maps integration, you need a Google maps API key, which you can obtain freely at the [Google Maps API Signup Page](http://code.google.com/apis/maps/signup.html).
16
 
18
 
19
  Events manager is fully customisable; you can customise the amount of data displayed and their format in events lists, pages and in the RSS feed. You can choose to show or hide the events page, and change its title.
20
 
21
+ Events Manager is fully localisable. IN this release you will find the Italian and Spanish localizations; German and Swedish will follow soon.
22
 
23
  == Installation ==
24
 
 
25
  1. Upload the `events-manager` folder to the `/wp-content/plugins/` directory
26
  2. Activate the plugin through the 'Plugins' menu in WordPress
27
  3. Add events list or calendars following the instructions in the Usage section.
28
 
29
+ Events Manager 1.* adopters should:
 
 
 
 
 
 
 
30
 
31
+ 1. backup their Wordpress database.
32
+ 2. deactivate Events Manager 1.\*
33
+ 3. delete Events Managers 1.* and upload Events Manager 2.* to their server
34
+ 4. activate Events Manager 2.*
35
 
36
+ Events Manager should take care of your events database migration automatically, but since this is a beta release it's much better to perform a database backup, as previously suggested.
 
37
 
38
+ == Usage ==
 
 
 
 
 
 
39
 
40
+ After the installation, Events Manager add a top level "Events" menu to your Wordpress Administration.
 
 
 
 
41
 
42
+ * The *Events* page lets you edit or delete the events. The *Add new* page lets you insert a new event.
43
+ In the event edit page you can specify the number of spaces available for your event. Yuo just need to turn on RSVP for the event and specify the spaces available in the right sidebar box.
44
+ When a visitor responds to your events, the box sill show you his reservation. You can remoe reservation by clicking on the *x* button or view the respondents data in a printable page.
45
+ * The *Locations* page lets you add, delete and edit locations directly. Locations are automatically added with events if not present, but this interface lets you customise your locations data and add a picture.
46
+ * The *People* page serves as a gathering point for the information about the people who reserved a space in your events.
47
+ * The *Settings* page allows a fine-grained control over the plugin. Here you can set the [format](#formatting-events) of events in the Events page.
48
 
49
+ Events list and calendars can be added to your blogs through widgets, shortcodes and template tags. See the full documentation at the [Events Manager Support Page](http://davidebenini.it/wordpress-plugins/events-manager/).
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  == Frequently Asked Questions ==
52
 
53
  = I enabled the Google Maps integration, but instead of the map there is a green background. What should I do? =
101
  2. The events management page.
102
  3. The Events Manager Options page.
103
 
 
 
 
 
 
 
 
 
 
104
  == Change Log ==
105
 
106
  1.0b1
132
  Fixed a bug loaded the Google Maps Api when deleting events.
133
  Fixed a bug that prevented validation in the default widget list item format.
134
 
135
+ 1.1b
136
+ Added a javascript datepicker
137
+
138
+ 2.0b1
139
+ Added locations support.
140
+ Added RSVP and people management.
141
+ Added repeated events.
142
+ Added multiple map.
143
+ Fixed a bug in calendars which displayed only the first events when more are present.