Restaurant Reservations - Version 1.3

Version Description

This update adds support for adding and editing bookings from the admin panel. The bookings panel now shows upcoming bookings by default. The Party field in the booking form is now a dropdown selection. Plus a bunch of new features and fixes. Read the full changelog for details.

Download this release

Release Info

Developer NateWr
Plugin Icon 128x128 Restaurant Reservations
Version 1.3
Comparing to
See all releases

Code changes from version 1.2.3 to 1.3

Files changed (70) hide show
  1. assets/addons-backup.json +11 -0
  2. assets/css/admin.css +243 -2
  3. assets/js/admin.js +312 -9
  4. assets/js/booking-form.js +170 -112
  5. includes/Addons.class.php +27 -16
  6. includes/AdminBookings.class.php +455 -0
  7. includes/Booking.class.php +88 -27
  8. includes/Compatibility.class.php +47 -0
  9. includes/CustomPostTypes.class.php +18 -18
  10. includes/Notification.Email.class.php +30 -16
  11. includes/Notification.class.php +3 -3
  12. includes/Notifications.class.php +17 -22
  13. includes/Settings.class.php +333 -117
  14. includes/WP_List_Table.BookingsTable.class.php +122 -53
  15. includes/WP_Widget.BookingFormWidget.class.php +2 -2
  16. includes/template-functions.php +98 -99
  17. languages/restaurant-reservations-de_DE.mo +0 -0
  18. languages/restaurant-reservations-de_DE.po +1441 -0
  19. languages/restaurant-reservations-es_CL.mo +0 -0
  20. languages/restaurant-reservations-es_CL.po +1201 -0
  21. languages/restaurant-reservations-nl_NL.MO +0 -0
  22. languages/{rtbdomain.pot → restaurant-reservations-nl_NL.PO} +747 -643
  23. languages/restaurant-reservations.pot +1263 -0
  24. lib/simple-admin-pages/README.md +37 -22
  25. lib/simple-admin-pages/classes/AdminPage.Menu.class.php +1 -1
  26. lib/simple-admin-pages/classes/AdminPage.Submenu.class.php +1 -1
  27. lib/simple-admin-pages/classes/AdminPage.Themes.class.php +1 -1
  28. lib/simple-admin-pages/classes/AdminPage.class.php +1 -1
  29. lib/simple-admin-pages/classes/AdminPageSection.class.php +1 -1
  30. lib/simple-admin-pages/classes/AdminPageSetting.Address.class.php +29 -24
  31. lib/simple-admin-pages/classes/AdminPageSetting.Editor.class.php +1 -1
  32. lib/simple-admin-pages/classes/AdminPageSetting.HTML.class.php +1 -1
  33. lib/simple-admin-pages/classes/AdminPageSetting.OpeningHours.class.php +1 -1
  34. lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php +65 -40
  35. lib/simple-admin-pages/classes/AdminPageSetting.Select.class.php +1 -1
  36. lib/simple-admin-pages/classes/AdminPageSetting.SelectPost.class.php +7 -5
  37. lib/simple-admin-pages/classes/AdminPageSetting.SelectTaxonomy.class.php +1 -1
  38. lib/simple-admin-pages/classes/AdminPageSetting.Text.class.php +1 -1
  39. lib/simple-admin-pages/classes/AdminPageSetting.Textarea.class.php +1 -1
  40. lib/simple-admin-pages/classes/AdminPageSetting.Toggle.class.php +1 -1
  41. lib/simple-admin-pages/classes/AdminPageSetting.class.php +34 -6
  42. lib/simple-admin-pages/classes/Library.class.php +3 -3
  43. lib/simple-admin-pages/lib/pickadate/legacy.js +125 -2
  44. lib/simple-admin-pages/lib/pickadate/picker.date.js +1347 -2
  45. lib/simple-admin-pages/lib/pickadate/picker.js +1117 -2
  46. lib/simple-admin-pages/lib/pickadate/picker.time.js +1007 -2
  47. lib/simple-admin-pages/lib/pickadate/themes/default.css +170 -2
  48. lib/simple-admin-pages/lib/pickadate/themes/default.date.css +301 -1
  49. lib/simple-admin-pages/lib/pickadate/themes/default.time.css +126 -1
  50. lib/simple-admin-pages/lib/pickadate/themes/rtl.css +27 -1
  51. lib/simple-admin-pages/lib/pickadate/translations/ca_ES.js +1 -0
  52. lib/simple-admin-pages/lib/pickadate/translations/da_DK.js +1 -0
  53. lib/simple-admin-pages/lib/pickadate/translations/de_DE.js +1 -0
  54. lib/simple-admin-pages/lib/pickadate/translations/fr_FR.js +4 -4
  55. lib/simple-admin-pages/lib/pickadate/translations/it_IT.js +10 -4
  56. lib/simple-admin-pages/lib/pickadate/translations/lt_LT.js +24 -0
  57. lib/simple-admin-pages/lib/pickadate/translations/lv_LV.js +13 -0
  58. lib/simple-admin-pages/lib/pickadate/translations/{no_NO.js → nb_NO.js} +1 -0
  59. lib/simple-admin-pages/lib/pickadate/translations/nl_NL.js +1 -0
  60. lib/simple-admin-pages/lib/pickadate/translations/pl_PL.js +4 -3
  61. lib/simple-admin-pages/lib/pickadate/translations/pt_BR.js +3 -2
  62. lib/simple-admin-pages/lib/pickadate/translations/pt_PT.js +6 -5
  63. lib/simple-admin-pages/lib/pickadate/translations/sl_SI.js +1 -0
  64. lib/simple-admin-pages/lib/pickadate/translations/sv_SE.js +10 -5
  65. lib/simple-admin-pages/lib/pickadate/translations/tr_TR.js +3 -2
  66. lib/simple-admin-pages/simple-admin-pages.php +0 -5
  67. readme.txt +28 -7
  68. restaurant-reservations.php +53 -60
  69. screenshot-10.png +0 -0
  70. screenshot-9.png +0 -0
assets/addons-backup.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id":"mailchimp-for-rtb",
4
+ "title":"MailChimp for Restaurant Reservations",
5
+ "url":"http:\/\/themeofthecrop.com\/plugin\/mailchimp-restaurant-reservations\/",
6
+ "price":"$20",
7
+ "img":"https:\/\/themeofthecrop.com\/promo\/plugins\/mailchimp-for-rtb.png",
8
+ "status":"released",
9
+ "description":"Subscribe emails from new restaurant reservations to your MailChimp mailing list."
10
+ }
11
+ ]
assets/css/admin.css CHANGED
@@ -56,8 +56,8 @@
56
  }
57
 
58
  #rtb-bookings-table tr.closed {
59
- opacity: 0.7;
60
- filter: opacity(alpha=70);
61
  }
62
  #rtb-bookings-table tr.closed:hover {
63
  opacity: 1;
@@ -69,11 +69,252 @@
69
  border-left: 4px solid #dd3d36;
70
  }
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  @media screen and (max-width: 782px) {
73
 
74
  #rtb-bookings-table .fixed .column-date {
75
  display: table-cell;
76
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
 
79
  /* Settings Pages (most of this is handled by the Simple Admin Pages library) */
56
  }
57
 
58
  #rtb-bookings-table tr.closed {
59
+ opacity: 0.6;
60
+ filter: opacity(alpha=60);
61
  }
62
  #rtb-bookings-table tr.closed:hover {
63
  opacity: 1;
69
  border-left: 4px solid #dd3d36;
70
  }
71
 
72
+ #rtb-bookings-table tr.pending .check-column input[type=checkbox] {
73
+ margin-left: 4px;
74
+ }
75
+
76
+ #rtb-bookings-table th#date {
77
+ width: auto;
78
+ }
79
+
80
+ #rtb-bookings-table th#party {
81
+ width: 3em;
82
+ }
83
+
84
+ #rtb-bookings-table th#message {
85
+ width: 5em;
86
+ }
87
+
88
+ #rtb-bookings-table .column-date .actions {
89
+ line-height: 28px;
90
+ opacity: 0;
91
+ -webkit-transition: opacity 0.3s 0;
92
+ -moz-transition: opacity 0.3s 0;
93
+ transition: opacity 0.3s 0;
94
+ }
95
+
96
+ #rtb-bookings-table tr:hover .column-date .actions {
97
+ opacity: 1;
98
+ }
99
+
100
+ #rtb-bookings-table .column-date .actions .trash {
101
+ color: #a00;
102
+ }
103
+
104
+ #rtb-bookings-table .column-date .actions .trash:hover {
105
+ color: red;
106
+ }
107
+
108
+ #rtb-bookings-table .column-date .status {
109
+ width: 0;
110
+ height: 0;
111
+ overflow: hidden;
112
+ line-height: 28px;
113
+ opacity: 0;
114
+ -webkit-transition: opacity 0.6s 0;
115
+ -moz-transition: opacity 0.6s 0;
116
+ transition: opacity 0.6s 0;
117
+ }
118
+
119
+ #rtb-bookings-table .column-date .status .spinner {
120
+ display: inline-block;
121
+ float: left;
122
+ margin: 4px 4px 0 0;
123
+ vertical-align: middle;
124
+ }
125
+
126
+ #rtb-bookings-table .column-date.loading .actions {
127
+ display: none;
128
+ }
129
+
130
+ #rtb-bookings-table .column-date.loading .status {
131
+ width: auto;
132
+ height: auto;
133
+ overflow: visible;
134
+ opacity: 0.5;
135
+ }
136
+
137
+ #rtb-bookings-table tr.notice td {
138
+ background: #2ea2cc;
139
+ color: #fff;
140
+ }
141
+
142
+ #rtb-bookings-table tr.notice.trash td {
143
+ background: #dd3d36;
144
+ }
145
+
146
  @media screen and (max-width: 782px) {
147
 
148
  #rtb-bookings-table .fixed .column-date {
149
  display: table-cell;
150
  }
151
+
152
+ #rtb-bookings-table th#party,
153
+ #rtb-bookings-table th#message {
154
+ width: auto;
155
+ }
156
+ }
157
+
158
+ /* Add/edit bookings modal */
159
+ .rtb-admin-modal {
160
+ position: fixed;
161
+ top: 0;
162
+ left: 0;
163
+ width: 100%;
164
+ height: 100%;
165
+ background: rgba(0, 0, 0, 0.8);
166
+ z-index: 3;
167
+ overflow-y: auto;
168
+ cursor: pointer;
169
+ visibility: hidden;
170
+ opacity: 0;
171
+ -webkit-transition: opacity 0.3s 0, visibility 0 0.3s;
172
+ -moz-transition: opacity 0.3s 0, visibility 0 0.3s;
173
+ transition: opacity 0.3s 0, visibility 0 0.3s;
174
+ }
175
+
176
+ .rtb-admin-modal.is-visible {
177
+ visibility: visible;
178
+ opacity: 1;
179
+ -webkit-transition: opacity 0.3s 0, visibility 0 0;
180
+ -moz-transition: opacity 0.3s 0, visibility 0 0;
181
+ transition: opacity 0.3s 0, visibility 0 0;
182
+ }
183
+
184
+ .rtb-admin-modal.is-visible .rtb-container {
185
+ -webkit-transform: translateY(0);
186
+ -moz-transform: translateY(0);
187
+ -ms-transform: translateY(0);
188
+ -o-transform: translateY(0);
189
+ transform: translateY(0);
190
+ }
191
+
192
+ .rtb-admin-modal .rtb-container {
193
+ position: relative;
194
+ width: 90%;
195
+ max-width: 20em;
196
+ padding: 2em;
197
+ background: #FFF;
198
+ margin: 3em auto 4em;
199
+ cursor: auto;
200
+ border-radius: 0.25em;
201
+ -webkit-transform: translateY(-30px);
202
+ -moz-transform: translateY(-30px);
203
+ -ms-transform: translateY(-30px);
204
+ -o-transform: translateY(-30px);
205
+ transform: translateY(-30px);
206
+ -webkit-transition-property: -webkit-transform;
207
+ -moz-transition-property: -moz-transform;
208
+ transition-property: transform;
209
+ -webkit-transition-duration: 0.3s;
210
+ -moz-transition-duration: 0.3s;
211
+ transition-duration: 0.3s;
212
+ }
213
+
214
+ #rtb-booking-modal fieldset {
215
+ padding: 0;
216
+ }
217
+
218
+ #rtb-booking-modal label {
219
+ color: #777;
220
+ font-style: italic;
221
+ }
222
+
223
+ #rtb-booking-modal button {
224
+ margin-top: 1em;
225
+ margin-right: 1em;
226
+ }
227
+
228
+ #rtb-booking-modal .button {
229
+ margin-top: 1em;
230
+ }
231
+
232
+ #rtb-booking-modal button,
233
+ #rtb-booking-modal .button {
234
+ opacity: 1;
235
+ transition: opacity .25s ease-in-out;
236
+ -moz-transition: opacity .25s ease-in-out;
237
+ -webkit-transition: opacity .25s ease-in-out;
238
+ }
239
+
240
+ #rtb-booking-modal button:disabled,
241
+ #rtb-booking-modal .button:disabled {
242
+ opacity: 0.5;
243
+ transition: opacity .25s ease-in-out;
244
+ -moz-transition: opacity .25s ease-in-out;
245
+ -webkit-transition: opacity .25s ease-in-out;
246
+ }
247
+
248
+ #rtb-booking-modal .action-status {
249
+ display: inline-block;
250
+ float: right;
251
+ margin-top: 1em;
252
+ opacity: 0;
253
+ transition: opacity .25s ease-in-out;
254
+ -moz-transition: opacity .25s ease-in-out;
255
+ -webkit-transition: opacity .25s ease-in-out;
256
+ }
257
+
258
+ #rtb-booking-modal .action-status.is-visible {
259
+ opacity: 1;
260
+ }
261
+
262
+ #rtb-booking-modal .action-status > span {
263
+ display: none;
264
+ background-position: 4px;
265
+ margin: 0;
266
+ height: 28px;
267
+ width: 28px;
268
+ line-height: 28px;
269
+ font-size: 28px;
270
+ }
271
+
272
+ #rtb-booking-modal .action-status > .spinner {
273
+ display: block;
274
+ }
275
+
276
+ #rtb-booking-modal .action-status > .success {
277
+ color: #7ad03a;
278
+ }
279
+
280
+ #rtb-booking-modal .action-status > .error {
281
+ color: #dd3d36;
282
+ }
283
+
284
+ #rtb-booking-modal .rtb-error {
285
+ background: #dd3d36;
286
+ }
287
+
288
+ #rtb-booking-modal .rtb-error a {
289
+ color: #fff;
290
+ }
291
+
292
+ #rtb-booking-modal input[type="text"],
293
+ #rtb-booking-modal input[type="email"],
294
+ #rtb-booking-modal textarea {
295
+ max-width: 100%;
296
+ }
297
+
298
+ .rtb-description {
299
+ margin: 0.5em 0;
300
+ color: #777;
301
+ max-height: 0;
302
+ overflow: hidden;
303
+ -webkit-transition: max-height 0.5s 0;
304
+ -moz-transition: max-height 0.5s 0;
305
+ transition: max-height 0.5s 0;
306
+ }
307
+
308
+ .rtb-description.is-visible {
309
+ max-height: 20em;
310
+ }
311
+
312
+ #rtb-error-modal .rtb-error-msg {
313
+ margin-bottom: 1em;
314
+ }
315
+ /* Hide the outer scrollbar when the modal is open */
316
+ .rtb-hide-body-scroll {
317
+ overflow: hidden !important;
318
  }
319
 
320
  /* Settings Pages (most of this is handled by the Simple Admin Pages library) */
assets/js/admin.js CHANGED
@@ -15,13 +15,316 @@ jQuery(document).ready(function ($) {
15
  $( '#' + message_id ).fadeIn();
16
  $(this).children( '.dashicons' ).removeClass( 'dashicons-testimonial' ).addClass( 'dashicons-welcome-comments' );
17
  }
18
-
19
  return false;
20
  });
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  // Show the addons
23
  if ( $( '#rtb-addons' ).length ) {
24
-
25
  var rtbAddons = {
26
 
27
  el: $( '#rtb-addons' ),
@@ -45,7 +348,7 @@ jQuery(document).ready(function ($) {
45
  rtbAddons.showError( r );
46
  }
47
  });
48
-
49
 
50
  });
51
  },
@@ -86,19 +389,19 @@ jQuery(document).ready(function ($) {
86
  } else if ( typeof addon.img !== 'undefind' ) {
87
  html += '<img src="' + addon.img + '">';
88
  }
89
-
90
  html += '<h3>' + addon.title + '</h3>';
91
 
92
  html += '<div class="details">';
93
-
94
  if ( typeof addon.description !== 'undefined' ) {
95
  html += '<div class="description">' + addon.description + '</div>';
96
  }
97
-
98
  if ( typeof addon.status !== 'undefined' ) {
99
 
100
  html += '<div class="action">';
101
-
102
  if ( addon.status === 'released' && typeof addon.url !== 'undefined' ) {
103
  html += '<a href="' + addon.url + '" class="button button-primary" target="_blank">';
104
 
@@ -119,7 +422,7 @@ jQuery(document).ready(function ($) {
119
 
120
  html += '</div>'; // .action
121
  }
122
-
123
  html += '</div>'; // .details
124
 
125
  html += '</div>'; // .addon
@@ -127,7 +430,7 @@ jQuery(document).ready(function ($) {
127
  return html;
128
  }
129
  };
130
-
131
  rtbAddons.load();
132
  }
133
 
15
  $( '#' + message_id ).fadeIn();
16
  $(this).children( '.dashicons' ).removeClass( 'dashicons-testimonial' ).addClass( 'dashicons-welcome-comments' );
17
  }
18
+
19
  return false;
20
  });
21
 
22
+ // Register clicks on edit/delete links
23
+ $( '#rtb-bookings-table .column-date .actions' ).click( function(e) {
24
+
25
+ var target = $(e.target);
26
+ var cell = target.parent().parent();
27
+
28
+ rtb_booking_loading_spinner( true, cell );
29
+
30
+ if ( target.data( 'action' ) == 'edit' ) {
31
+ rtb_get_booking( target.data( 'id' ), cell );
32
+
33
+ } else if ( target.data( 'action' ) == 'trash' ) {
34
+ rtb_trash_booking( target.data( 'id' ), cell );
35
+ }
36
+
37
+ e.preventDefault();
38
+ });
39
+
40
+ /**
41
+ * Show/hide loading spinner when edit/delete link clicked
42
+ */
43
+ function rtb_booking_loading_spinner( loading, cell ) {
44
+ if ( loading ) {
45
+ cell.addClass( 'loading' );
46
+ } else {
47
+ cell.removeClass( 'loading' );
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Modal to add/edit bookings from the admin
53
+ */
54
+ var rtb_booking_modal = $( '#rtb-booking-modal' );
55
+ var rtb_booking_modal_fields = rtb_booking_modal.find( '#rtb-booking-form-fields' );
56
+ var rtb_booking_modal_submit = rtb_booking_modal.find( 'button' );
57
+ var rtb_booking_modal_cancel = rtb_booking_modal.find( '#rtb-cancel-booking-modal' );
58
+ var rtb_booking_modal_action_status = rtb_booking_modal.find( '.action-status' );
59
+ var rtb_booking_modal_error = $( '#rtb-error-modal' );
60
+ var rtb_booking_modal_error_msg = rtb_booking_modal_error.find( '.rtb-error-msg' );
61
+
62
+ /**
63
+ * Show or hide the booking form modal
64
+ */
65
+ function rtb_toggle_booking_form_modal( show, fields, booking ) {
66
+
67
+ if ( show ) {
68
+ rtb_booking_modal.scrollTop( 0 ).addClass( 'is-visible' );
69
+
70
+ if ( typeof fields !== 'undefined' ) {
71
+ rtb_booking_modal_fields.html( fields );
72
+ rtb_booking_form.init();
73
+ rtb_init_booking_form_modal_fields();
74
+ }
75
+
76
+ if ( typeof booking == 'undefined' ) {
77
+ rtb_booking_modal_fields.find( '#rtb-post-status' ).val( 'confirmed' );
78
+ rtb_booking_modal_submit.html( rtb_admin.strings.add_booking );
79
+ } else {
80
+ rtb_booking_modal_submit.html( rtb_admin.strings.edit_booking );
81
+ rtb_booking_modal.find( 'input[name=ID]' ).val( booking.ID );
82
+ }
83
+
84
+ $( 'body' ).addClass( 'rtb-hide-body-scroll' );
85
+
86
+ } else {
87
+ rtb_booking_modal.removeClass( 'is-visible' );
88
+ rtb_booking_modal.find( '.rtb-error' ).remove();
89
+ rtb_booking_modal.find( '.notifications-description' ).removeClass( 'is-visible' );
90
+ rtb_booking_modal_action_status.removeClass( 'is-visible' );
91
+ rtb_reset_booking_form_modal_fields();
92
+ rtb_booking_modal_submit.removeData( 'id' );
93
+ rtb_booking_modal_submit.prop( 'disabled', false );
94
+ rtb_booking_modal_cancel.prop( 'disabled', false );
95
+ rtb_booking_modal.find( 'input[name=ID]' ).val( '' );
96
+
97
+ $( 'body' ).removeClass( 'rtb-hide-body-scroll' );
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Show or hide the booking form error modal
103
+ */
104
+ function rtb_toggle_booking_form_error_modal( show, msg ) {
105
+
106
+ if ( show ) {
107
+ rtb_booking_modal_error_msg.html( msg );
108
+ rtb_booking_modal_error.addClass( 'is-visible' );
109
+
110
+ } else {
111
+ rtb_booking_modal_error.removeClass( 'is-visible' );
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Initialize form field events
117
+ */
118
+ function rtb_init_booking_form_modal_fields() {
119
+
120
+ // Show full description for notifications toggle
121
+ rtb_booking_modal_fields.find( '.rtb-description-prompt' ).click( function() {
122
+ $(this).parent().siblings( '.rtb-description' ).addClass( 'is-visible' );
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Reset booking form fields
128
+ */
129
+ function rtb_reset_booking_form_modal_fields() {
130
+ rtb_booking_modal_fields.find( 'input, select, textarea' ).val( '' );
131
+ rtb_booking_modal_fields.find( 'input[name=rtb-notifications]' ).removeAttr( 'checked' );
132
+ }
133
+
134
+ /**
135
+ * Retrieve booking from the database
136
+ */
137
+ function rtb_get_booking( id, cell ) {
138
+
139
+ var params = {};
140
+
141
+ params.action = 'rtb-admin-booking-modal';
142
+ params.nonce = rtb_admin.nonce;
143
+ params.booking = {
144
+ 'ID': id
145
+ };
146
+
147
+ var data = $.param( params );
148
+
149
+ var jqhxr = $.get( ajaxurl, data, function( r ) {
150
+
151
+ if ( r.success ) {
152
+ rtb_toggle_booking_form_modal( true, r.data.fields, r.data.booking );
153
+
154
+ } else {
155
+
156
+ if ( typeof r.data.error == 'undefined' ) {
157
+ rtb_toggle_booking_form_error_modal( true, rtb_admin.strings.error_unspecified );
158
+ } else {
159
+ rtb_toggle_booking_form_error_modal( true, r.data.msg );
160
+ }
161
+ }
162
+
163
+ rtb_booking_loading_spinner( false, cell );
164
+ });
165
+ }
166
+
167
+ /**
168
+ * Trash booking
169
+ */
170
+ function rtb_trash_booking( id, cell ) {
171
+
172
+ var params = {};
173
+
174
+ params.action = 'rtb-admin-trash-booking';
175
+ params.nonce = rtb_admin.nonce;
176
+ params.booking = id;
177
+
178
+ var data = $.param( params );
179
+
180
+ var jqhxr = $.post( ajaxurl, data, function( r ) {
181
+
182
+ if ( r.success ) {
183
+
184
+ cell.parent().fadeOut( 500, function() {
185
+ $(this).remove();
186
+ });
187
+
188
+ var trash_count_el = $( '#rtb-bookings-table .subsubsub .trash .count' );
189
+ var trash_count = parseInt( trash_count_el.html().match(/\d+/), 10 ) + 1;
190
+ trash_count_el.html( '(' + trash_count + ')' );
191
+
192
+ } else {
193
+
194
+ if ( typeof r.data == 'undefined' || typeof r.data.error == 'undefined' ) {
195
+ rtb_toggle_booking_form_error_modal( true, rtb_admin.strings.error_unspecified );
196
+ } else {
197
+ rtb_toggle_booking_form_error_modal( true, r.data.msg );
198
+ }
199
+ }
200
+
201
+ rtb_booking_loading_spinner( false, cell );
202
+ });
203
+
204
+ }
205
+
206
+ /**
207
+ * Show the appropriate result status icon
208
+ */
209
+ function rtb_show_action_status( status ) {
210
+
211
+ rtb_booking_modal_action_status.find( 'span' ).hide();
212
+
213
+ if ( status === true ) {
214
+ rtb_booking_modal_action_status.find( '.success' ).show();
215
+ } else if ( status === false ) {
216
+ rtb_booking_modal_action_status.find( '.error' ).show();
217
+ } else {
218
+ rtb_booking_modal_action_status.find( '.spinner' ).show();
219
+ }
220
+ }
221
+
222
+ // Initialize form field events on load
223
+ rtb_init_booking_form_modal_fields();
224
+
225
+ // Reset the form on load
226
+ // This fixes a strange bug in Firefox where disabled buttons would
227
+ // persist after the page refreshed. I'm guessing its a cache issue
228
+ // but this will just reset everything again
229
+ rtb_toggle_booking_form_modal( false );
230
+
231
+ // Show booking form modal
232
+ $( '.add-booking' ).click( function() {
233
+ rtb_toggle_booking_form_modal( true );
234
+ });
235
+
236
+ // Close booking form modal when background or cancel button is clicked
237
+ rtb_booking_modal.click( function(e) {
238
+ if ( $(e.target).is( rtb_booking_modal ) ) {
239
+ rtb_toggle_booking_form_modal( false );
240
+ }
241
+
242
+ if ( $(e.target).is( rtb_booking_modal_cancel ) && rtb_booking_modal_cancel.prop( 'disabled' ) === false ) {
243
+ rtb_toggle_booking_form_modal( false );
244
+ }
245
+ });
246
+
247
+ // Close booking form modal and error modal when ESC is keyed
248
+ $(document).keyup( function(e) {
249
+ if ( e.which == '27' ) {
250
+ rtb_toggle_booking_form_modal( false );
251
+ rtb_toggle_booking_form_error_modal( false );
252
+ }
253
+ });
254
+
255
+ // Close booking form error modal when background or cancel button is clicked
256
+ rtb_booking_modal_error.click( function(e) {
257
+ if ( $(e.target).is( rtb_booking_modal_error ) || $(e.target).is( rtb_booking_modal_error.find( 'a.button' ) ) ) {
258
+ rtb_toggle_booking_form_error_modal( false );
259
+ }
260
+ });
261
+
262
+ // Submit booking form modal
263
+ rtb_booking_modal_submit.click( function(e) {
264
+
265
+ e.preventDefault();
266
+ e.stopPropagation();
267
+
268
+ if ( $(this).prop( 'disabled' ) === true ) {
269
+ return;
270
+ }
271
+
272
+ // Loading
273
+ rtb_booking_modal_submit.prop( 'disabled', true );
274
+ rtb_booking_modal_cancel.prop( 'disabled', true );
275
+ rtb_booking_modal_action_status.addClass( 'is-visible' );
276
+ rtb_show_action_status( 'loading' );
277
+
278
+ var params = {};
279
+
280
+ params.action = 'rtb-admin-booking-modal';
281
+ params.nonce = rtb_admin.nonce;
282
+ params.booking = rtb_booking_modal.find( 'form' ).serializeArray();
283
+
284
+ var data = $.param( params );
285
+
286
+ var jqhxr = $.post( ajaxurl, data, function( r ) {
287
+
288
+ if ( r.success ) {
289
+
290
+ // Refresh the page so that the new details are visible
291
+ window.location.reload();
292
+
293
+ } else {
294
+
295
+ // Validation failed
296
+ if ( r.data.error == 'invalid_booking_data' ) {
297
+
298
+ // Replace form fields with HTML returned
299
+ rtb_booking_modal_fields.html( r.data.fields );
300
+ rtb_booking_form.init();
301
+ rtb_init_booking_form_modal_fields();
302
+
303
+ // Logged out
304
+ } else if ( r.data.error == 'loggedout' ) {
305
+ rtb_booking_modal_fields.after( '<div class="rtb-error">' + r.data.msg + '</div>' );
306
+
307
+ // Unspecified error
308
+ } else {
309
+ rtb_booking_modal_fields.after( '<div class="rtb-error">' + rtb_admin.strings.error_unspecified + '</div>' );
310
+ }
311
+
312
+ rtb_booking_modal_cancel.prop( 'disabled', false );
313
+ rtb_booking_modal_submit.prop( 'disabled', false );
314
+ }
315
+
316
+ rtb_show_action_status( r.success );
317
+
318
+ // Hide result status icon after a few seconds
319
+ setTimeout( function() {
320
+ rtb_booking_modal.find( '.action-status' ).removeClass( 'is-visible' );
321
+ }, 4000 );
322
+ });
323
+ });
324
+
325
  // Show the addons
326
  if ( $( '#rtb-addons' ).length ) {
327
+
328
  var rtbAddons = {
329
 
330
  el: $( '#rtb-addons' ),
348
  rtbAddons.showError( r );
349
  }
350
  });
351
+
352
 
353
  });
354
  },
389
  } else if ( typeof addon.img !== 'undefind' ) {
390
  html += '<img src="' + addon.img + '">';
391
  }
392
+
393
  html += '<h3>' + addon.title + '</h3>';
394
 
395
  html += '<div class="details">';
396
+
397
  if ( typeof addon.description !== 'undefined' ) {
398
  html += '<div class="description">' + addon.description + '</div>';
399
  }
400
+
401
  if ( typeof addon.status !== 'undefined' ) {
402
 
403
  html += '<div class="action">';
404
+
405
  if ( addon.status === 'released' && typeof addon.url !== 'undefined' ) {
406
  html += '<a href="' + addon.url + '" class="button button-primary" target="_blank">';
407
 
422
 
423
  html += '</div>'; // .action
424
  }
425
+
426
  html += '</div>'; // .details
427
 
428
  html += '</div>'; // .addon
430
  return html;
431
  }
432
  };
433
+
434
  rtbAddons.load();
435
  }
436
 
assets/js/booking-form.js CHANGED
@@ -1,138 +1,170 @@
1
  /* Javascript for Restaurant Reservations booking form */
 
 
 
2
  jQuery(document).ready(function ($) {
3
 
4
  /**
5
- * Scroll to the first error message on the booking form
6
  */
7
- if ( $( '.rtb-booking-form .rtb-error' ).length ) {
8
- $('html, body').animate({
9
- scrollTop: $( '.rtb-booking-form .rtb-error' ).first().offset().top + -40
10
- }, 500);
11
- }
12
 
13
- /**
14
- * Show the message field on the booking form
15
- */
16
- $( '.rtb-booking-form .add-message a' ).click( function() {
17
- $(this).hide();
18
- $(this).parent().siblings( '.message' ).addClass( 'message-open' );
19
 
20
- return false;
21
- });
 
 
22
 
23
- /**
24
- * Enable datepickers on load
25
- */
26
- if ( typeof rtb_pickadate !== 'undefined' ) {
27
-
28
- // Declare datepicker
29
- var date_input = $( '#rtb-date' ).pickadate({
30
- format: rtb_pickadate.date_format,
31
- formatSubmit: 'yyyy/mm/dd',
32
- hiddenName: true,
33
- min: true,
34
- container: 'body',
35
-
36
- // Select the value when loaded if a value has been set
37
- onStart: function() {
38
- if ( $( '#rtb-date' ).val() !== '' ) {
39
- var date = new Date( $( '#rtb-date' ).val() );
40
- if ( Object.prototype.toString.call( date ) === "[object Date]" ) {
41
- this.set( 'select', date );
42
- }
43
- }
44
- }
45
  });
46
 
47
- // Declare timepicker
48
- var time_input = $( '#rtb-time' ).pickatime({
49
- format: rtb_pickadate.time_format,
50
- formatSubmit: 'h:i A',
51
- hiddenName: true,
52
- interval: parseInt( rtb_pickadate.time_interval, 10 ),
53
- container: 'body',
54
-
55
- // Select the value when loaded if a value has been set
56
- onStart: function() {
57
- if ( $( '#rtb-time' ).val() !== '' ) {
58
- var today = new Date();
59
- var today_date = today.getFullYear() + '/' + ( today.getMonth() + 1 ) + '/' + today.getDate();
60
- var time = new Date( today_date + ' ' + $( '#rtb-time' ).val() );
61
- if ( Object.prototype.toString.call( time ) === "[object Date]" ) {
62
- this.set( 'select', time );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
  }
65
- }
66
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
- var datepicker = date_input.pickadate( 'picker' );
69
- var timepicker = time_input.pickatime( 'picker' );
70
 
71
- if ( typeof datepicker == 'undefined' ) {
72
- return;
73
- }
74
 
75
- // Pass conditional configuration parameters
76
- if ( rtb_pickadate.disable_dates.length ) {
77
-
78
- // Update weekday dates if start of the week has been modified
79
- if ( typeof datepicker.component.settings.firstDay == 'number' ) {
80
- var weekday_num = 0;
81
- for ( var disable_key in rtb_pickadate.disable_dates ) {
82
- if ( typeof rtb_pickadate.disable_dates[disable_key] == 'number' ) {
83
- weekday_num = rtb_pickadate.disable_dates[disable_key] - datepicker.component.settings.firstDay;
84
- if ( weekday_num < 1 ) {
85
- weekday_num = 7;
 
 
86
  }
87
- rtb_pickadate.disable_dates[disable_key] = weekday_num;
88
  }
89
  }
90
- }
91
 
92
- datepicker.set( 'disable', rtb_pickadate.disable_dates );
93
- }
94
 
95
- if ( rtb_pickadate.late_bookings === '1440' ) {
96
- datepicker.set( 'min', 1 );
97
- }
98
 
99
- // If no date has been set, select today's date if it's a valid
100
- // date. User may opt not to do this in the settings.
101
- if ( $( '#rtb-date' ).val() === '' && !$( '.rtb-booking-form .date .rtb-error' ).length ) {
102
-
103
- if ( rtb_pickadate.date_onload == 'soonest' ) {
104
- datepicker.set( 'select', new Date() );
105
- } else if ( rtb_pickadate.date_onload !== 'empty' ) {
106
- var dateToVerify = datepicker.component.create( new Date() );
107
- var isDisabled = datepicker.component.disabled( dateToVerify );
108
- if ( !isDisabled ) {
109
- datepicker.set( 'select', dateToVerify );
 
110
  }
111
  }
112
- }
113
 
114
- // Update timepicker on pageload and whenever the datepicker is closed
115
- rtb_update_timepicker_range();
116
- datepicker.on( {
117
- close: function() {
118
- rtb_update_timepicker_range();
119
- }
120
- });
121
- }
 
122
 
123
- // Update the timepicker's range based on the currently selected date
124
- function rtb_update_timepicker_range() {
 
 
125
 
126
  // Reset enabled/disabled rules on this timepicker
127
- timepicker.set( 'enable', false );
128
- timepicker.set( 'disable', false );
129
 
130
- if ( datepicker.get() === '' ) {
131
- timepicker.set( 'disable', true );
132
  return;
133
  }
134
 
135
- selected_date = new Date( datepicker.get( 'select', 'yyyy/mm/dd' ) );
136
  var selected_date_year = selected_date.getFullYear();
137
  var selected_date_month = selected_date.getMonth();
138
  var selected_date_date = selected_date.getDate();
@@ -141,7 +173,7 @@ jQuery(document).ready(function ($) {
141
  // times subsequently declared are valid. Any time that doesn't fall
142
  // within those declarations is invalid.
143
  // See: http://amsul.ca/pickadate.js/time.htm#disable-times-all
144
- var valid_times = [ { from: [0, 0], to: [24, 0] } ];
145
 
146
  // Check if this date is an exception to the rules
147
  if ( typeof rtb_pickadate.schedule_closed != 'undefined' ) {
@@ -161,7 +193,7 @@ jQuery(document).ready(function ($) {
161
 
162
  // Closed all day
163
  if ( typeof rtb_pickadate.schedule_closed[closed_key].time == 'undefined' ) {
164
- timepicker.set( 'disable', [ true ] );
165
 
166
  return;
167
  }
@@ -188,7 +220,7 @@ jQuery(document).ready(function ($) {
188
 
189
  // Exit early if this date is an exception
190
  if ( valid_times.length > 1 ) {
191
- timepicker.set( 'disable', valid_times );
192
 
193
  return;
194
  }
@@ -221,7 +253,7 @@ jQuery(document).ready(function ($) {
221
 
222
  // Closed all day
223
  if ( typeof rtb_pickadate.schedule_open[open_key].time == 'undefined' ) {
224
- timepicker.set( 'disable', [ true ] );
225
 
226
  return;
227
  }
@@ -251,7 +283,7 @@ jQuery(document).ready(function ($) {
251
 
252
  // Pass any valid times located
253
  if ( valid_times.length > 1 ) {
254
- timepicker.set( 'disable', valid_times );
255
 
256
  return;
257
  }
@@ -259,10 +291,36 @@ jQuery(document).ready(function ($) {
259
  }
260
 
261
  // Set it to always open if no rules have been defined
262
- timepicker.set( 'enable', true );
263
- timepicker.set( 'disable', false );
264
 
265
  return;
266
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
 
268
  });
1
  /* Javascript for Restaurant Reservations booking form */
2
+
3
+ var rtb_booking_form = rtb_booking_form || {};
4
+
5
  jQuery(document).ready(function ($) {
6
 
7
  /**
8
+ * Initialize the booking form when loaded
9
  */
10
+ rtb_booking_form.init = function() {
 
 
 
 
11
 
12
+ // Scroll to the first error message on the booking form
13
+ if ( $( '.rtb-booking-form .rtb-error' ).length ) {
14
+ $('html, body').animate({
15
+ scrollTop: $( '.rtb-booking-form .rtb-error' ).first().offset().top + -40
16
+ }, 500);
17
+ }
18
 
19
+ // Show the message field on the booking form
20
+ $( '.rtb-booking-form .add-message a' ).click( function() {
21
+ $(this).hide();
22
+ $(this).parent().siblings( '.message' ).addClass( 'message-open' );
23
 
24
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  });
26
 
27
+ // Show the message field on load if not empty
28
+ if ( $.trim( $( '.rtb-booking-form .message textarea' ).val() ) ) {
29
+ $( '.rtb-booking-form .add-message a' ).trigger( 'click' );
30
+ }
31
+
32
+ // Enable datepickers on load
33
+ if ( typeof rtb_pickadate !== 'undefined' ) {
34
+
35
+ // Declare datepicker
36
+ var date_input = $( '#rtb-date' ).pickadate({
37
+ format: rtb_pickadate.date_format,
38
+ formatSubmit: 'yyyy/mm/dd',
39
+ hiddenName: true,
40
+ min: true,
41
+ container: 'body',
42
+
43
+ // Workaround bug in current version of pickadate.js
44
+ // https://github.com/amsul/pickadate.js/issues/609
45
+ onOpen: function() {
46
+ input = document.getElementById( 'rtb-date' );
47
+ window.scrollTo( 0, input.offsetTop );
48
+ },
49
+ onClose: function() {
50
+ input = document.getElementById( 'rtb-date' );
51
+ window.scrollTo( 0, input.offsetTop );
52
+ },
53
+
54
+ // Select the value when loaded if a value has been set
55
+ onStart: function() {
56
+ if ( $( '#rtb-date' ).val() !== '' ) {
57
+ var date = new Date( $( '#rtb-date' ).val() );
58
+ if ( Object.prototype.toString.call( date ) === "[object Date]" ) {
59
+ this.set( 'select', date );
60
+ }
61
  }
62
  }
63
+ });
64
+
65
+ // Declare timepicker
66
+ var time_input = $( '#rtb-time' ).pickatime({
67
+ format: rtb_pickadate.time_format,
68
+ formatSubmit: 'h:i A',
69
+ hiddenName: true,
70
+ interval: parseInt( rtb_pickadate.time_interval, 10 ),
71
+ container: 'body',
72
+
73
+ // Workaround bug in current version of pickadate.js
74
+ // https://github.com/amsul/pickadate.js/issues/609
75
+ onOpen: function() {
76
+ input = document.getElementById( 'rtb-time' );
77
+ window.scrollTo( 0, input.offsetTop );
78
+ },
79
+ onClose: function() {
80
+ input = document.getElementById( 'rtb-time' );
81
+ window.scrollTo( 0, input.offsetTop );
82
+ },
83
+
84
+ // Select the value when loaded if a value has been set
85
+ onStart: function() {
86
+ if ( $( '#rtb-time' ).val() !== '' ) {
87
+ var today = new Date();
88
+ var today_date = today.getFullYear() + '/' + ( today.getMonth() + 1 ) + '/' + today.getDate();
89
+ var time = new Date( today_date + ' ' + $( '#rtb-time' ).val() );
90
+ if ( Object.prototype.toString.call( time ) === "[object Date]" ) {
91
+ this.set( 'select', time );
92
+ }
93
+ }
94
+ }
95
+ });
96
 
97
+ rtb_booking_form.datepicker = date_input.pickadate( 'picker' );
98
+ rtb_booking_form.timepicker = time_input.pickatime( 'picker' );
99
 
100
+ if ( typeof rtb_booking_form.datepicker == 'undefined' ) {
101
+ return;
102
+ }
103
 
104
+ // Pass conditional configuration parameters
105
+ if ( rtb_pickadate.disable_dates.length ) {
106
+
107
+ // Update weekday dates if start of the week has been modified
108
+ if ( typeof rtb_booking_form.datepicker.component.settings.firstDay == 'number' ) {
109
+ var weekday_num = 0;
110
+ for ( var disable_key in rtb_pickadate.disable_dates ) {
111
+ if ( typeof rtb_pickadate.disable_dates[disable_key] == 'number' ) {
112
+ weekday_num = rtb_pickadate.disable_dates[disable_key] - rtb_booking_form.datepicker.component.settings.firstDay;
113
+ if ( weekday_num < 1 ) {
114
+ weekday_num = 7;
115
+ }
116
+ rtb_pickadate.disable_dates[disable_key] = weekday_num;
117
  }
 
118
  }
119
  }
 
120
 
121
+ rtb_booking_form.datepicker.set( 'disable', rtb_pickadate.disable_dates );
122
+ }
123
 
124
+ if ( rtb_pickadate.late_bookings === '1440' ) {
125
+ rtb_booking_form.datepicker.set( 'min', 1 );
126
+ }
127
 
128
+ // If no date has been set, select today's date if it's a valid
129
+ // date. User may opt not to do this in the settings.
130
+ if ( $( '#rtb-date' ).val() === '' && !$( '.rtb-booking-form .date .rtb-error' ).length ) {
131
+
132
+ if ( rtb_pickadate.date_onload == 'soonest' ) {
133
+ rtb_booking_form.datepicker.set( 'select', new Date() );
134
+ } else if ( rtb_pickadate.date_onload !== 'empty' ) {
135
+ var dateToVerify = rtb_booking_form.datepicker.component.create( new Date() );
136
+ var isDisabled = rtb_booking_form.datepicker.component.disabled( dateToVerify );
137
+ if ( !isDisabled ) {
138
+ rtb_booking_form.datepicker.set( 'select', dateToVerify );
139
+ }
140
  }
141
  }
 
142
 
143
+ // Update timepicker on pageload and whenever the datepicker is closed
144
+ rtb_booking_form.update_timepicker_range();
145
+ rtb_booking_form.datepicker.on( {
146
+ close: function() {
147
+ rtb_booking_form.update_timepicker_range();
148
+ }
149
+ });
150
+ }
151
+ };
152
 
153
+ /**
154
+ * Update the timepicker's range based on the currently selected date
155
+ */
156
+ rtb_booking_form.update_timepicker_range = function() {
157
 
158
  // Reset enabled/disabled rules on this timepicker
159
+ rtb_booking_form.timepicker.set( 'enable', false );
160
+ rtb_booking_form.timepicker.set( 'disable', false );
161
 
162
+ if ( rtb_booking_form.datepicker.get() === '' ) {
163
+ rtb_booking_form.timepicker.set( 'disable', true );
164
  return;
165
  }
166
 
167
+ selected_date = new Date( rtb_booking_form.datepicker.get( 'select', 'yyyy/mm/dd' ) );
168
  var selected_date_year = selected_date.getFullYear();
169
  var selected_date_month = selected_date.getMonth();
170
  var selected_date_date = selected_date.getDate();
173
  // times subsequently declared are valid. Any time that doesn't fall
174
  // within those declarations is invalid.
175
  // See: http://amsul.ca/pickadate.js/time.htm#disable-times-all
176
+ var valid_times = [ rtb_booking_form.get_outer_time_range() ];
177
 
178
  // Check if this date is an exception to the rules
179
  if ( typeof rtb_pickadate.schedule_closed != 'undefined' ) {
193
 
194
  // Closed all day
195
  if ( typeof rtb_pickadate.schedule_closed[closed_key].time == 'undefined' ) {
196
+ rtb_booking_form.timepicker.set( 'disable', [ true ] );
197
 
198
  return;
199
  }
220
 
221
  // Exit early if this date is an exception
222
  if ( valid_times.length > 1 ) {
223
+ rtb_booking_form.timepicker.set( 'disable', valid_times );
224
 
225
  return;
226
  }
253
 
254
  // Closed all day
255
  if ( typeof rtb_pickadate.schedule_open[open_key].time == 'undefined' ) {
256
+ rtb_booking_form.timepicker.set( 'disable', [ true ] );
257
 
258
  return;
259
  }
283
 
284
  // Pass any valid times located
285
  if ( valid_times.length > 1 ) {
286
+ rtb_booking_form.timepicker.set( 'disable', valid_times );
287
 
288
  return;
289
  }
291
  }
292
 
293
  // Set it to always open if no rules have been defined
294
+ rtb_booking_form.timepicker.set( 'enable', true );
295
+ rtb_booking_form.timepicker.set( 'disable', false );
296
 
297
  return;
298
+ };
299
+
300
+ /**
301
+ * Get the outer times to exclude based on the time interval
302
+ *
303
+ * This is a work-around for a bug in pickadate.js
304
+ * https://github.com/amsul/pickadate.js/issues/614
305
+ */
306
+ rtb_booking_form.get_outer_time_range = function() {
307
+
308
+ var interval = rtb_booking_form.timepicker.get( 'interval' );
309
+
310
+ var hour = 24;
311
+
312
+ while ( interval >= 60 ) {
313
+ hour--;
314
+ interval -= 60;
315
+ }
316
+
317
+ if ( interval > 0 ) {
318
+ hour--;
319
+ interval = 60 - interval;
320
+ }
321
+
322
+ return { from: [0, 0], to: [ hour, interval ] };
323
+ };
324
 
325
+ rtb_booking_form.init();
326
  });
includes/Addons.class.php CHANGED
@@ -78,20 +78,29 @@ class rtbAddons {
78
  */
79
  public function enqueue_admin_assets() {
80
 
 
 
 
 
 
81
  $screen = get_current_screen();
82
- if ( $screen->base == 'bookings_page_rtb-addons' ) {
 
 
 
 
83
  wp_localize_script(
84
  'rtb-admin',
85
  'rtb_addons',
86
  array(
87
  'nonce' => wp_create_nonce( 'rtb-addons' ),
88
  'strings' => array(
89
- 'loading' => __( 'Loading', RTB_TEXTDOMAIN ),
90
- 'error_unknown' => _x( 'An unknown error occured.', 'Error message when retrieving list of addons', RTB_TEXTDOMAIN ),
91
- 'installed' => _x( 'Already Installed', 'Label for an addon that is already installed and activated.', RTB_TEXTDOMAIN ),
92
- 'coming_soon' => _x( 'Coming Soon', 'Label for an addon that is not yet released.', RTB_TEXTDOMAIN ),
93
- 'free' => _x( 'Free', 'Label for an addon that is free.', RTB_TEXTDOMAIN ),
94
- 'learn_more' => _x( 'Get It', 'Label for an addon that is released.', RTB_TEXTDOMAIN ),
95
  )
96
  )
97
  );
@@ -105,8 +114,8 @@ class rtbAddons {
105
 
106
  add_submenu_page(
107
  'rtb-bookings',
108
- _x( 'Addons', 'Title of addons page', RTB_TEXTDOMAIN ),
109
- _x( 'Addons', 'Title of addons page in the admin menu', RTB_TEXTDOMAIN ),
110
  'manage_options',
111
  'rtb-addons',
112
  array( $this, 'show_admin_addons_page' )
@@ -123,7 +132,7 @@ class rtbAddons {
123
  ?>
124
 
125
  <div class="wrap">
126
- <h2><?php _e( 'Addons for Restaurant Reservations', RTB_TEXTDOMAIN ); ?></h2>
127
  <?php do_action( 'rtb_addons_pre' ); ?>
128
  <div id="rtb-addons">
129
  <div class="rtb-loading">
@@ -145,7 +154,7 @@ class rtbAddons {
145
  wp_send_json_error(
146
  array(
147
  'error' => 'loggedout',
148
- 'msg' => __( 'You have been logged out. Please login again to retrieve the addons.', RTB_TEXTDOMAIN ),
149
  )
150
  );
151
  }
@@ -161,7 +170,7 @@ class rtbAddons {
161
  wp_send_json_error(
162
  array(
163
  'error' => 'nopriv',
164
- 'msg' => __( 'You do not have permission to access this page. Please login to an administrator account if you have one.', RTB_TEXTDOMAIN ),
165
  )
166
  );
167
  }
@@ -170,14 +179,16 @@ class rtbAddons {
170
  $ch = curl_init();
171
  curl_setopt( $ch, CURLOPT_URL, $url );
172
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' ) );
173
- curl_setopt( $ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0' );
174
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
175
  curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );
176
  $result = curl_exec($ch);
177
  curl_close($ch);
178
-
179
- } else {
180
  $result = @file_get_contents( $url );
 
 
181
  }
182
 
183
  if ( $result ) {
@@ -187,7 +198,7 @@ class rtbAddons {
187
  wp_send_json_error(
188
  array(
189
  'error' => 'apifailed',
190
- 'msg' => __( 'The addons list could not be retrieved. Please <a href="">try again</a>. If the problem persists over time, please report it on the <a href="http://wordpress.org/support/plugin/restaurant-reservations" target="_blank">support forums</a>.', RTB_TEXTDOMAIN ),
191
  )
192
  );
193
  }
78
  */
79
  public function enqueue_admin_assets() {
80
 
81
+ // Use the page reference in $admin_page_hooks because
82
+ // it changes in SOME hooks when it is translated.
83
+ // https://core.trac.wordpress.org/ticket/18857
84
+ global $admin_page_hooks;
85
+
86
  $screen = get_current_screen();
87
+ if ( empty( $screen ) || empty( $admin_page_hooks['rtb-bookings'] ) ) {
88
+ return;
89
+ }
90
+
91
+ if ( $screen->base == $admin_page_hooks['rtb-bookings'] . '_page_rtb-addons' ) {
92
  wp_localize_script(
93
  'rtb-admin',
94
  'rtb_addons',
95
  array(
96
  'nonce' => wp_create_nonce( 'rtb-addons' ),
97
  'strings' => array(
98
+ 'loading' => __( 'Loading', 'restaurant-reservations' ),
99
+ 'error_unknown' => _x( 'An unknown error occured.', 'Error message when retrieving list of addons', 'restaurant-reservations' ),
100
+ 'installed' => _x( 'Already Installed', 'Label for an addon that is already installed and activated.', 'restaurant-reservations' ),
101
+ 'coming_soon' => _x( 'Coming Soon', 'Label for an addon that is not yet released.', 'restaurant-reservations' ),
102
+ 'free' => _x( 'Free', 'Label for an addon that is free.', 'restaurant-reservations' ),
103
+ 'learn_more' => _x( 'Get It', 'Label for an addon that is released.', 'restaurant-reservations' ),
104
  )
105
  )
106
  );
114
 
115
  add_submenu_page(
116
  'rtb-bookings',
117
+ _x( 'Addons', 'Title of addons page', 'restaurant-reservations' ),
118
+ _x( 'Addons', 'Title of addons page in the admin menu', 'restaurant-reservations' ),
119
  'manage_options',
120
  'rtb-addons',
121
  array( $this, 'show_admin_addons_page' )
132
  ?>
133
 
134
  <div class="wrap">
135
+ <h2><?php _e( 'Addons for Restaurant Reservations', 'restaurant-reservations' ); ?></h2>
136
  <?php do_action( 'rtb_addons_pre' ); ?>
137
  <div id="rtb-addons">
138
  <div class="rtb-loading">
154
  wp_send_json_error(
155
  array(
156
  'error' => 'loggedout',
157
+ 'msg' => __( 'You have been logged out. Please login again to retrieve the addons.', 'restaurant-reservations' ),
158
  )
159
  );
160
  }
170
  wp_send_json_error(
171
  array(
172
  'error' => 'nopriv',
173
+ 'msg' => __( 'You do not have permission to access this page. Please login to an administrator account if you have one.', 'restaurant-reservations' ),
174
  )
175
  );
176
  }
179
  $ch = curl_init();
180
  curl_setopt( $ch, CURLOPT_URL, $url );
181
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' ) );
182
+ curl_setopt( $ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0' );
183
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
184
  curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );
185
  $result = curl_exec($ch);
186
  curl_close($ch);
187
+
188
+ } elseif ( ini_get( 'allow_url_fopen' ) ) {
189
  $result = @file_get_contents( $url );
190
+ } else {
191
+ $result = @file_get_contents( RTB_PLUGIN_DIR . '/assets/addons-backup.json' );
192
  }
193
 
194
  if ( $result ) {
198
  wp_send_json_error(
199
  array(
200
  'error' => 'apifailed',
201
+ 'msg' => __( 'The addons list could not be retrieved. Please <a href="">try again</a>. If the problem persists over time, please report it on the <a href="http://wordpress.org/support/plugin/restaurant-reservations" target="_blank">support forums</a>.', 'restaurant-reservations' ),
202
  )
203
  );
204
  }
includes/AdminBookings.class.php ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined( 'ABSPATH' ) ) exit;
3
+
4
+ if ( !class_exists( 'rtbAdminBookings' ) ) {
5
+ /**
6
+ * Class to handle the admin bookings page for Restaurant Reservations
7
+ *
8
+ * @since 1.3
9
+ */
10
+ class rtbAdminBookings {
11
+
12
+ public function __construct() {
13
+
14
+ // Add the admin menu
15
+ add_action( 'admin_menu', array( $this, 'add_menu_page' ) );
16
+
17
+ // Print the booking form modal
18
+ add_action( 'admin_footer-toplevel_page_rtb-bookings', array( $this, 'print_booking_form_modal' ) );
19
+
20
+ // Receive Ajax requests
21
+ add_action( 'wp_ajax_nopriv_rtb-admin-booking-modal' , array( $this , 'nopriv_ajax' ) );
22
+ add_action( 'wp_ajax_rtb-admin-booking-modal', array( $this, 'booking_modal_ajax' ) );
23
+ add_action( 'wp_ajax_nopriv_rtb-admin-trash-booking' , array( $this , 'nopriv_ajax' ) );
24
+ add_action( 'wp_ajax_rtb-admin-trash-booking', array( $this, 'trash_booking_ajax' ) );
25
+
26
+ // Validate post status and notification fields
27
+ add_action( 'rtb_validate_booking_submission', array( $this, 'validate_admin_fields' ) );
28
+
29
+ // Set post status when adding to the database
30
+ add_filter( 'rtb_insert_booking_data', array( $this, 'insert_booking_data' ), 10, 2 );
31
+
32
+ }
33
+
34
+ /**
35
+ * Add the top-level admin menu page
36
+ * @since 0.0.1
37
+ */
38
+ public function add_menu_page() {
39
+
40
+ add_menu_page(
41
+ _x( 'Bookings', 'Title of admin page that lists bookings', 'restaurant-reservations' ),
42
+ _x( 'Bookings', 'Title of bookings admin menu item', 'restaurant-reservations' ),
43
+ 'manage_bookings',
44
+ 'rtb-bookings',
45
+ array( $this, 'show_admin_bookings_page' ),
46
+ 'dashicons-calendar',
47
+ '26.2987'
48
+ );
49
+
50
+ }
51
+
52
+ /**
53
+ * Display the admin bookings page
54
+ * @since 0.0.1
55
+ */
56
+ public function show_admin_bookings_page() {
57
+
58
+ require_once( RTB_PLUGIN_DIR . '/includes/WP_List_Table.BookingsTable.class.php' );
59
+ $bookings_table = new rtbBookingsTable();
60
+ $bookings_table->prepare_items();
61
+ ?>
62
+
63
+ <div class="wrap">
64
+ <h2>
65
+ <?php _e( 'Restaurant Bookings', 'restaurant-reservations' ); ?>
66
+ <a href="#" class="add-new-h2 add-booking"><?php _e( 'Add New', 'restaurant-reservations' ); ?></a>
67
+ </h2>
68
+
69
+ <?php do_action( 'rtb_bookings_table_top' ); ?>
70
+ <form id="rtb-bookings-table" method="POST" action="">
71
+ <input type="hidden" name="post_type" value="<?php echo RTB_BOOKING_POST_TYPE; ?>" />
72
+ <input type="hidden" name="page" value="rtb-bookings">
73
+
74
+ <?php $bookings_table->views(); ?>
75
+ <?php $bookings_table->advanced_filters(); ?>
76
+ <?php $bookings_table->display(); ?>
77
+ </form>
78
+ <?php do_action( 'rtb_bookings_table_btm' ); ?>
79
+ </div>
80
+
81
+ <?php
82
+ }
83
+
84
+ /**
85
+ * Print the booking form modal container on the admin bookings page
86
+ * @since 0.0.1
87
+ */
88
+ public function print_booking_form_modal() {
89
+ ?>
90
+
91
+ <div id="rtb-booking-modal" class="rtb-admin-modal">
92
+ <div class="rtb-booking-form rtb-container">
93
+ <form method="POST">
94
+ <input type="hidden" name="action" value="admin_booking_request">
95
+ <input type="hidden" name="ID" value="">
96
+
97
+ <?php
98
+ /**
99
+ * The generated fields are wrapped in a div so we can
100
+ * replace its contents with an HTML blob passed back from
101
+ * an Ajax request. This way the field data and error
102
+ * messages are always populated from the same server-side
103
+ * code.
104
+ */
105
+ ?>
106
+ <div id="rtb-booking-form-fields">
107
+ <?php echo $this->print_booking_form_fields(); ?>
108
+ </div>
109
+
110
+ <button type="submit" class="button-primary">
111
+ <?php _e( 'Add Booking', 'restaurant-reservations' ); ?>
112
+ </button>
113
+ <a href="#" class="button" id="rtb-cancel-booking-modal">
114
+ <?php _e( 'Cancel', 'restaurant-reservations' ); ?>
115
+ </a>
116
+ <div class="action-status">
117
+ <span class="spinner loading"></span>
118
+ <span class="dashicons dashicons-no-alt error"></span>
119
+ <span class="dashicons dashicons-yes success"></span>
120
+ </div>
121
+ </form>
122
+ </div>
123
+ </div>
124
+ <!-- Restaurant Reservations error message modal -->
125
+ <div id="rtb-error-modal" class="rtb-admin-modal">
126
+ <div class="rtb-error rtb-container">
127
+ <div class="rtb-error-msg"></div>
128
+ <a href="#" class="button"><?php _e( 'Close', 'restaurant-reservations' ); ?></a>
129
+ </div>
130
+ </div>
131
+
132
+ <?php
133
+ }
134
+
135
+ /**
136
+ * Retrieve booking form fields used in the admin booking modal. These
137
+ * fields are also passed back with ajax requests since they render error
138
+ * messages and populate fields with validated data.
139
+ * @since 0.0.1
140
+ */
141
+ public function print_booking_form_fields() {
142
+
143
+ global $rtb_controller;
144
+
145
+ // Add post status and notification fields to admin booking form
146
+ add_filter( 'rtb_booking_form_fields', array( $this, 'add_admin_fields' ), 20, 2 );
147
+
148
+ // Retrieve the form fields
149
+ $fields = $rtb_controller->settings->get_booking_form_fields( $rtb_controller->request );
150
+
151
+ ob_start();
152
+ ?>
153
+
154
+ <?php foreach( $fields as $fieldset => $contents ) : ?>
155
+ <fieldset class="<?php echo $fieldset; ?>">
156
+ <?php
157
+ foreach( $contents['fields'] as $slug => $field ) {
158
+
159
+ $args = empty( $field['callback_args'] ) ? null : $field['callback_args'];
160
+
161
+ call_user_func( $field['callback'], $slug, $field['title'], $field['request_input'], $args );
162
+ }
163
+ ?>
164
+ </fieldset>
165
+ <?php endforeach;
166
+
167
+ // Remove the admin fields filter
168
+ remove_filter( 'rtb_booking_form_fields', array( $this, 'add_admin_fields' ) );
169
+
170
+ return ob_get_clean();
171
+ }
172
+
173
+ /**
174
+ * Add the post status and notifications fields to the booking form fields
175
+ * @since 1.3
176
+ */
177
+ public function add_admin_fields( $fields, $request ) {
178
+
179
+ if ( !is_admin() || !current_user_can( 'manage_bookings' ) ) {
180
+ return $fields;
181
+ }
182
+
183
+ global $rtb_controller;
184
+
185
+ // Get all valid booking statuses
186
+ $booking_statuses = array();
187
+ foreach( $rtb_controller->cpts->booking_statuses as $status => $args ) {
188
+ $booking_statuses[ $status ] = $args['label'];
189
+ }
190
+
191
+ $fields['admin'] = array(
192
+ 'fields' => array(
193
+ 'post-status' => array(
194
+ 'title' => __( 'Booking Status', 'restaurant-reservations' ),
195
+ 'request_input' => empty( $request->post_status ) ? '' : $request->post_status,
196
+ 'callback' => 'rtb_print_form_select_field',
197
+ 'callback_args' => array(
198
+ 'options' => $booking_statuses,
199
+ )
200
+ ),
201
+ 'notifications' => array(
202
+ 'title' => __( 'Send notifications', 'restaurant-reservations' ),
203
+ 'request_input' => empty( $request->send_notifications ) ? false : $request->send_notifications,
204
+ 'callback' => array( $this, 'print_form_send_notifications_field' ),
205
+ 'callback_args' => array(
206
+ 'description' => array(
207
+ 'prompt' => __( 'Learn more', 'restaurant-reservations' ),
208
+ 'text' => __( "When adding a booking or changing a booking's status with this form, no email notifications will be sent. Check this option if you want to send email notifications.", 'restaurant-reservations' ),
209
+ ),
210
+ ),
211
+ ),
212
+ ),
213
+ );
214
+
215
+ return $fields;
216
+ }
217
+
218
+
219
+ /**
220
+ * Print a field to toggle notifications when adding/editing a booking from
221
+ * the admin
222
+ * @since 1.3
223
+ */
224
+ function print_form_send_notifications_field( $slug, $title, $value, $args ) {
225
+
226
+ $slug = esc_attr( $slug );
227
+ $title = esc_attr( $title );
228
+ $value = (bool) $value;
229
+ $description = empty( $args['description'] ) || empty( $args['description']['prompt'] ) || empty( $args['description']['text'] ) ? null : $args['description'];
230
+ ?>
231
+
232
+ <div class="<?php echo $slug; ?>">
233
+ <?php echo rtb_print_form_error( $slug ); ?>
234
+ <label>
235
+ <input type="checkbox" name="rtb-<?php echo esc_attr( $slug ); ?>" value="1"<?php checked( $value ); ?>>
236
+ <?php echo $title; ?>
237
+ <?php if ( !empty( $description ) ) : ?>
238
+ <a href="#" class="rtb-description-prompt">
239
+ <?php echo $description['prompt']; ?>
240
+ </a>
241
+ <?php endif; ?>
242
+ </label>
243
+ <?php if ( !empty( $description ) ) : ?>
244
+ <div class="rtb-description">
245
+ <?php echo $description['text']; ?>
246
+ </div>
247
+ <?php endif; ?>
248
+ </div>
249
+
250
+ <?php
251
+ }
252
+
253
+ /**
254
+ * Handle ajax requests from the admin bookings area from logged out users
255
+ * @since 1.3
256
+ */
257
+ public function nopriv_ajax() {
258
+
259
+ wp_send_json_error(
260
+ array(
261
+ 'error' => 'loggedout',
262
+ 'msg' => sprintf( __( 'You have been logged out. Please %slogin again%s.', 'restaurant-reservations' ), '<a href="' . wp_login_url( admin_url( 'admin.php?page=rtb-bookings&status=pending' ) ) . '">', '</a>' ),
263
+ )
264
+ );
265
+ }
266
+
267
+ /**
268
+ * Handle ajax requests from the admin bookings area
269
+ * @since 1.3
270
+ */
271
+ public function booking_modal_ajax() {
272
+
273
+ global $rtb_controller;
274
+
275
+ // Authenticate request
276
+ if ( !check_ajax_referer( 'rtb-admin', 'nonce' ) || !current_user_can( 'manage_bookings' ) ) {
277
+ $this->nopriv_ajax();
278
+ }
279
+
280
+ // Retrieve a booking with a GET request
281
+ if ( !empty( $_GET['booking'] ) && !empty( $_GET['booking']['ID'] ) ) {
282
+
283
+ $id = (int) $_GET['booking']['ID'];
284
+
285
+ require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
286
+ $rtb_controller->request = new rtbBooking();
287
+ $result = $rtb_controller->request->load_post( $id );
288
+
289
+ if ( $result ) {
290
+
291
+ // Don't allow editing of trashed bookings. This wil force
292
+ // appropriate use of the trash status and (hopefully) prevent
293
+ // mistakes in booking management.
294
+ if ( $rtb_controller->request->post_status == 'trash' ) {
295
+ wp_send_json_error(
296
+ array(
297
+ 'error' => 'booking_trashed',
298
+ 'msg' => sprintf( __( 'This booking has been sent to the %sTrash%s where it can not be edited. Set the booking to Pending or Confirmed to edit it.', 'restaurant-reservations' ), '<a href="' . admin_url( 'admin.php?page=rtb-bookings&status=trash' ) . '">', '</a>' ),
299
+ )
300
+ );
301
+ }
302
+
303
+ $rtb_controller->request->prepare_request_data();
304
+ wp_send_json_success(
305
+ array(
306
+ 'booking' => $rtb_controller->request,
307
+ 'fields' => $this->print_booking_form_fields(),
308
+ )
309
+ );
310
+
311
+ } else {
312
+ wp_send_json_error(
313
+ array(
314
+ 'error' => 'booking_not_found',
315
+ 'msg' => __( 'The booking could not be retrieved. Please reload the page and try again.', 'restaurant-reservations' ),
316
+ )
317
+ );
318
+ }
319
+
320
+ // Insert or update a booking with a POST request
321
+ } elseif ( !empty( $_POST['booking'] ) ) {
322
+
323
+ // Set up $_POST object for validation
324
+ foreach( $_POST['booking'] as $field ) {
325
+ $_POST[ $field['name'] ] = $field['value'];
326
+ }
327
+
328
+ require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
329
+ $rtb_controller->request = new rtbBooking();
330
+
331
+ // Add an ID if we're updating the post
332
+ if ( !empty( $_POST['ID'] ) ) {
333
+ $rtb_controller->request->ID = (int) $_POST['ID'];
334
+ }
335
+
336
+ // Disable notifications
337
+ $this->maybe_disable_notifications();
338
+
339
+ $result = $rtb_controller->request->insert_booking();
340
+
341
+ if ( $result ) {
342
+ wp_send_json_success(
343
+ array(
344
+ 'booking' => $rtb_controller->request,
345
+ )
346
+ );
347
+ } else {
348
+ wp_send_json_error(
349
+ array(
350
+ 'error' => 'invalid_booking_data',
351
+ 'booking' => $rtb_controller->request,
352
+ 'fields' => $this->print_booking_form_fields(),
353
+ )
354
+ );
355
+ }
356
+ }
357
+
358
+ // Fallback to a valid error
359
+ wp_send_json_error();
360
+ }
361
+
362
+ /**
363
+ * Set booking status to trash
364
+ * @since 1.3
365
+ */
366
+ public function trash_booking_ajax() {
367
+
368
+ global $rtb_controller;
369
+
370
+ // Authenticate request
371
+ if ( !check_ajax_referer( 'rtb-admin', 'nonce' ) || !current_user_can( 'manage_bookings' ) || empty( $_POST['booking'] ) ) {
372
+ $this->nopriv_ajax();
373
+ }
374
+
375
+ $id = (int) $_POST['booking'];
376
+
377
+ $result = wp_trash_post( $id );
378
+
379
+ if ( $result === false ) {
380
+ wp_send_json_error(
381
+ array(
382
+ 'error' => 'trash_failed',
383
+ 'msg' => __( 'Unable to trash this post. Please try again. If you continue to have trouble, please refresh the page.', 'restaurant-reservations' ),
384
+ )
385
+ );
386
+
387
+ } else {
388
+ wp_send_json_success(
389
+ array(
390
+ 'booking' => $id,
391
+ )
392
+ );
393
+ }
394
+
395
+
396
+
397
+ }
398
+
399
+ /**
400
+ * Validate post status and notification fields
401
+ * @since 1.3
402
+ */
403
+ public function validate_admin_fields( $booking ) {
404
+
405
+ // Only validate in the admin
406
+ if ( !$_POST['action'] || $_POST['action'] !== 'admin_booking_request' ) {
407
+ return;
408
+ }
409
+
410
+ global $rtb_controller;
411
+
412
+ // Disable Notifications
413
+ $booking->send_notifications = empty( $_POST['rtb-notifications'] ) ? false : true;
414
+ }
415
+
416
+ /**
417
+ * Adjust post status when adding/editing a booking from the admin area
418
+ * @since 1.3
419
+ */
420
+ public function insert_booking_data( $args, $booking ) {
421
+
422
+ // Validate user request
423
+ if ( empty( $_POST['action'] ) || $_POST['action'] !== 'admin_booking_request' || !current_user_can( 'manage_bookings' ) ) {
424
+ return $args;
425
+ }
426
+
427
+ if ( !empty( $booking->post_status ) ) {
428
+ $args['post_status'] = $booking->post_status;
429
+ }
430
+
431
+ return $args;
432
+ }
433
+
434
+ /**
435
+ * Maybe disable notifications when adding/editing bookings from the
436
+ * admin booking modal
437
+ * @since 1.3
438
+ */
439
+ public function maybe_disable_notifications() {
440
+
441
+ // Don't disable notifications if they have opted to send them
442
+ if ( !empty( $_POST['rtb-notifications'] ) ) {
443
+ return;
444
+ }
445
+
446
+ // Disable all notifications. This filter is here in case a
447
+ // third-party sets up a notification that they don't want to be
448
+ // disabled even if the user has opted not to send notifications
449
+ // To exempt a notification, hook into the filter and copy it
450
+ // from $rtb_notifications to the empty array.
451
+ global $rtb_controller;
452
+ $rtb_controller->notifications->notifications = apply_filters( 'rtb_admin_disabled_notifications_exemption', array(), $rtb_controller->notifications->notifications );
453
+ }
454
+ }
455
+ } // endif;
includes/Booking.class.php CHANGED
@@ -60,7 +60,7 @@ class rtbBooking {
60
  $this->ID = $post->ID;
61
  $this->name = $post->post_title;
62
  $this->date = $post->post_date;
63
- $this->message = apply_filters( 'the_content', $post->post_content );
64
  $this->post_status = $post->post_status;
65
 
66
  $this->load_post_metadata();
@@ -95,6 +95,22 @@ class rtbBooking {
95
  $this->date_submission = $meta['date_submission'];
96
  }
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  /**
99
  * Format date
100
  * @since 0.0.1
@@ -121,6 +137,12 @@ class rtbBooking {
121
 
122
  $this->request_processed = true;
123
 
 
 
 
 
 
 
124
  $this->validate_submission();
125
  if ( $this->is_valid_submission() === false ) {
126
  return false;
@@ -132,7 +154,7 @@ class rtbBooking {
132
  $this->request_inserted = true;
133
  }
134
 
135
- do_action( 'rtb_insert_booking', $this );
136
 
137
  return true;
138
  }
@@ -153,7 +175,7 @@ class rtbBooking {
153
  $this->validation_errors[] = array(
154
  'field' => 'date',
155
  'error_msg' => 'Booking request missing date',
156
- 'message' => __( 'Please enter the date you would like to book.', RTB_TEXTDOMAIN ),
157
  );
158
 
159
  } else {
@@ -163,7 +185,7 @@ class rtbBooking {
163
  $this->validation_errors[] = array(
164
  'field' => 'date',
165
  'error_msg' => $e->getMessage(),
166
- 'message' => __( 'The date you entered is not valid. Please select from one of the dates in the calendar.', RTB_TEXTDOMAIN ),
167
  );
168
  }
169
  }
@@ -174,7 +196,7 @@ class rtbBooking {
174
  $this->validation_errors[] = array(
175
  'field' => 'time',
176
  'error_msg' => 'Booking request missing time',
177
- 'message' => __( 'Please enter the time you would like to book.', RTB_TEXTDOMAIN ),
178
  );
179
 
180
  } else {
@@ -184,7 +206,7 @@ class rtbBooking {
184
  $this->validation_errors[] = array(
185
  'field' => 'time',
186
  'error_msg' => $e->getMessage(),
187
- 'message' => __( 'The time you entered is not valid. Please select from one of the times provided.', RTB_TEXTDOMAIN ),
188
  );
189
  }
190
  }
@@ -201,7 +223,7 @@ class rtbBooking {
201
  $this->validation_errors[] = array(
202
  'field' => 'time',
203
  'error_msg' => 'Booking request too far in the future',
204
- 'message' => sprintf( __( 'Sorry, bookings can not be made more than %s days in advance.', RTB_TEXTDOMAIN ), $early_bookings ),
205
  );
206
  }
207
  }
@@ -212,7 +234,7 @@ class rtbBooking {
212
  $this->validation_errors[] = array(
213
  'field' => 'time',
214
  'error_msg' => 'Booking request in the past',
215
- 'message' => __( 'Sorry, bookings can not be made in the past.', RTB_TEXTDOMAIN ),
216
  );
217
  }
218
 
@@ -220,11 +242,11 @@ class rtbBooking {
220
  $late_bookings_seconds = $late_bookings * 60; // Late bookings allowance in seconds
221
  if ( $request->format( 'U' ) < ( current_time( 'timestamp' ) + $late_bookings_seconds ) ) {
222
  if ( $late_bookings >= 1440 ) {
223
- $late_bookings_message = sprintf( __( 'Sorry, bookings must be made more than %s days in advance.', RTB_TEXTDOMAIN ), $late_bookings / 1440 );
224
  } elseif ( $late_bookings >= 60 ) {
225
- $late_bookings_message = sprintf( __( 'Sorry, bookings must be made more than %s hours in advance.', RTB_TEXTDOMAIN ), $late_bookings / 60 );
226
  } else {
227
- $late_bookings_message = sprintf( __( 'Sorry, bookings must be made more than %s mings in advance.', RTB_TEXTDOMAIN ), $late_bookings );
228
  }
229
  $this->validation_errors[] = array(
230
  'field' => 'time',
@@ -263,7 +285,7 @@ class rtbBooking {
263
  $this->validation_errors[] = array(
264
  'field' => 'date',
265
  'error_msg' => 'Booking request made on invalid date or time in an exception rule',
266
- 'message' => __( 'Sorry, no bookings are being accepted then.', RTB_TEXTDOMAIN ),
267
  );
268
  }
269
  }
@@ -315,13 +337,13 @@ class rtbBooking {
315
  $this->validation_errors[] = array(
316
  'field' => 'date',
317
  'error_msg' => 'Booking request made on an invalid date',
318
- 'message' => __( 'Sorry, no bookings are being accepted on that date.', RTB_TEXTDOMAIN ),
319
  );
320
  } elseif ( !$time_is_valid ) {
321
  $this->validation_errors[] = array(
322
  'field' => 'time',
323
  'error_msg' => 'Booking request made at an invalid time',
324
- 'message' => __( 'Sorry, no bookings are being accepted at that time.', RTB_TEXTDOMAIN ),
325
  );
326
  }
327
  }
@@ -343,31 +365,27 @@ class rtbBooking {
343
  $this->validation_errors[] = array(
344
  'field' => 'name',
345
  'post_variable' => $this->name,
346
- 'message' => __( 'Please enter a name for this booking.', RTB_TEXTDOMAIN ),
347
  );
348
  }
349
 
350
  // Party
351
- $this->party = empty( $_POST['rtb-party'] ) ? '' : sanitize_text_field( stripslashes_deep( $_POST['rtb-party'] ) );
352
  if ( empty( $this->party ) ) {
353
  $this->validation_errors[] = array(
354
  'field' => 'party',
355
  'post_variable' => $this->party,
356
- 'message' => __( 'Please let us know how many people will be in your party.', RTB_TEXTDOMAIN ),
357
  );
358
 
359
  // Check party size
360
- // If the user has entered a party size like "five" or "3-4" or
361
- // something like that, let's go ahead and allow it. Restaurant manager
362
- // can choose to accept or deny it. We'll only evaluate the max party
363
- // size criteria on pure digits ("2" or "10").
364
- } elseif ( ctype_digit( $this->party ) ) {
365
  $party_size = $rtb_controller->settings->get_setting( 'party-size' );
366
- if ( !empty( $party_size ) && $party_size < (int) $this->party ) {
367
  $this->validation_errors[] = array(
368
  'field' => 'party',
369
  'post_variable' => $this->party,
370
- 'message' => sprintf( __( 'We only accept bookings for parties of up to %d people.', RTB_TEXTDOMAIN ), $party_size ),
371
  );
372
  }
373
  }
@@ -378,13 +396,32 @@ class rtbBooking {
378
  $this->validation_errors[] = array(
379
  'field' => 'email',
380
  'post_variable' => $this->email,
381
- 'message' => __( 'Please enter an email address so we can confirm your booking.', RTB_TEXTDOMAIN ),
382
  );
383
  }
384
 
385
  // Phone/Message
386
  $this->phone = empty( $_POST['rtb-phone'] ) ? '' : sanitize_text_field( stripslashes_deep( $_POST['rtb-phone'] ) );
387
- $this->message = empty( $_POST['rtb-message'] ) ? '' : sanitize_text_field( stripslashes_deep( $_POST['rtb-message'] ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
 
389
  do_action( 'rtb_validate_booking_submission', $this );
390
 
@@ -392,12 +429,32 @@ class rtbBooking {
392
 
393
  /**
394
  * Check if submission is valid
 
395
  * @since 0.0.1
396
  */
397
  public function is_valid_submission() {
 
398
  if ( !count( $this->validation_errors ) ) {
399
  return true;
400
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  return false;
402
  }
403
 
@@ -412,9 +469,13 @@ class rtbBooking {
412
  'post_title' => $this->name,
413
  'post_content' => $this->message,
414
  'post_date' => $this->date,
415
- 'post_status' => 'pending',
416
  );
417
 
 
 
 
 
418
  $args = apply_filters( 'rtb_insert_booking_data', $args, $this );
419
 
420
  $id = wp_insert_post( $args );
60
  $this->ID = $post->ID;
61
  $this->name = $post->post_title;
62
  $this->date = $post->post_date;
63
+ $this->message = $post->post_content;
64
  $this->post_status = $post->post_status;
65
 
66
  $this->load_post_metadata();
95
  $this->date_submission = $meta['date_submission'];
96
  }
97
 
98
+ /**
99
+ * Prepare booking data loaded from the database for display in a booking
100
+ * form as request fields. This is used, eg, for splitting datetime values
101
+ * into date and time fields.
102
+ * @since 1.3
103
+ */
104
+ public function prepare_request_data() {
105
+
106
+ // Split $date to $request_date and $request_time
107
+ if ( empty( $this->request_date ) || empty( $this->request_time ) ) {
108
+ $date = new DateTime( $this->date );
109
+ $this->request_date = $date->format( 'Y/m/d' );
110
+ $this->request_time = $date->format( 'h:i A' );
111
+ }
112
+ }
113
+
114
  /**
115
  * Format date
116
  * @since 0.0.1
137
 
138
  $this->request_processed = true;
139
 
140
+ if ( empty( $this->ID ) ) {
141
+ $action = 'insert';
142
+ } else {
143
+ $action = 'update';
144
+ }
145
+
146
  $this->validate_submission();
147
  if ( $this->is_valid_submission() === false ) {
148
  return false;
154
  $this->request_inserted = true;
155
  }
156
 
157
+ do_action( 'rtb_' . $action . '_booking', $this );
158
 
159
  return true;
160
  }
175
  $this->validation_errors[] = array(
176
  'field' => 'date',
177
  'error_msg' => 'Booking request missing date',
178
+ 'message' => __( 'Please enter the date you would like to book.', 'restaurant-reservations' ),
179
  );
180
 
181
  } else {
185
  $this->validation_errors[] = array(
186
  'field' => 'date',
187
  'error_msg' => $e->getMessage(),
188
+ 'message' => __( 'The date you entered is not valid. Please select from one of the dates in the calendar.', 'restaurant-reservations' ),
189
  );
190
  }
191
  }
196
  $this->validation_errors[] = array(
197
  'field' => 'time',
198
  'error_msg' => 'Booking request missing time',
199
+ 'message' => __( 'Please enter the time you would like to book.', 'restaurant-reservations' ),
200
  );
201
 
202
  } else {
206
  $this->validation_errors[] = array(
207
  'field' => 'time',
208
  'error_msg' => $e->getMessage(),
209
+ 'message' => __( 'The time you entered is not valid. Please select from one of the times provided.', 'restaurant-reservations' ),
210
  );
211
  }
212
  }
223
  $this->validation_errors[] = array(
224
  'field' => 'time',
225
  'error_msg' => 'Booking request too far in the future',
226
+ 'message' => sprintf( __( 'Sorry, bookings can not be made more than %s days in advance.', 'restaurant-reservations' ), $early_bookings ),
227
  );
228
  }
229
  }
234
  $this->validation_errors[] = array(
235
  'field' => 'time',
236
  'error_msg' => 'Booking request in the past',
237
+ 'message' => __( 'Sorry, bookings can not be made in the past.', 'restaurant-reservations' ),
238
  );
239
  }
240
 
242
  $late_bookings_seconds = $late_bookings * 60; // Late bookings allowance in seconds
243
  if ( $request->format( 'U' ) < ( current_time( 'timestamp' ) + $late_bookings_seconds ) ) {
244
  if ( $late_bookings >= 1440 ) {
245
+ $late_bookings_message = sprintf( __( 'Sorry, bookings must be made more than %s days in advance.', 'restaurant-reservations' ), $late_bookings / 1440 );
246
  } elseif ( $late_bookings >= 60 ) {
247
+ $late_bookings_message = sprintf( __( 'Sorry, bookings must be made more than %s hours in advance.', 'restaurant-reservations' ), $late_bookings / 60 );
248
  } else {
249
+ $late_bookings_message = sprintf( __( 'Sorry, bookings must be made more than %s mings in advance.', 'restaurant-reservations' ), $late_bookings );
250
  }
251
  $this->validation_errors[] = array(
252
  'field' => 'time',
285
  $this->validation_errors[] = array(
286
  'field' => 'date',
287
  'error_msg' => 'Booking request made on invalid date or time in an exception rule',
288
+ 'message' => __( 'Sorry, no bookings are being accepted then.', 'restaurant-reservations' ),
289
  );
290
  }
291
  }
337
  $this->validation_errors[] = array(
338
  'field' => 'date',
339
  'error_msg' => 'Booking request made on an invalid date',
340
+ 'message' => __( 'Sorry, no bookings are being accepted on that date.', 'restaurant-reservations' ),
341
  );
342
  } elseif ( !$time_is_valid ) {
343
  $this->validation_errors[] = array(
344
  'field' => 'time',
345
  'error_msg' => 'Booking request made at an invalid time',
346
+ 'message' => __( 'Sorry, no bookings are being accepted at that time.', 'restaurant-reservations' ),
347
  );
348
  }
349
  }
365
  $this->validation_errors[] = array(
366
  'field' => 'name',
367
  'post_variable' => $this->name,
368
+ 'message' => __( 'Please enter a name for this booking.', 'restaurant-reservations' ),
369
  );
370
  }
371
 
372
  // Party
373
+ $this->party = empty( $_POST['rtb-party'] ) ? '' : absint( $_POST['rtb-party'] );
374
  if ( empty( $this->party ) ) {
375
  $this->validation_errors[] = array(
376
  'field' => 'party',
377
  'post_variable' => $this->party,
378
+ 'message' => __( 'Please let us know how many people will be in your party.', 'restaurant-reservations' ),
379
  );
380
 
381
  // Check party size
382
+ } else {
 
 
 
 
383
  $party_size = $rtb_controller->settings->get_setting( 'party-size' );
384
+ if ( !empty( $party_size ) && $party_size < $this->party ) {
385
  $this->validation_errors[] = array(
386
  'field' => 'party',
387
  'post_variable' => $this->party,
388
+ 'message' => sprintf( __( 'We only accept bookings for parties of up to %d people.', 'restaurant-reservations' ), $party_size ),
389
  );
390
  }
391
  }
396
  $this->validation_errors[] = array(
397
  'field' => 'email',
398
  'post_variable' => $this->email,
399
+ 'message' => __( 'Please enter an email address so we can confirm your booking.', 'restaurant-reservations' ),
400
  );
401
  }
402
 
403
  // Phone/Message
404
  $this->phone = empty( $_POST['rtb-phone'] ) ? '' : sanitize_text_field( stripslashes_deep( $_POST['rtb-phone'] ) );
405
+ $this->message = empty( $_POST['rtb-message'] ) ? '' : nl2br( wp_kses_post( stripslashes_deep( $_POST['rtb-message'] ) ) );
406
+
407
+ // Post Status (define a default post status is none passed)
408
+ if ( !empty( $_POST['rtb-post-status'] ) && array_key_exists( $_POST['rtb-post-status'], $rtb_controller->cpts->booking_statuses ) ) {
409
+ $this->status = sanitize_text_field( stripslashes_deep( $_POST['rtb-post-status'] ) );
410
+ } else {
411
+ $this->status = 'pending';
412
+ }
413
+
414
+ // Check if any required fields are empty
415
+ $required_fields = $rtb_controller->settings->get_required_fields();
416
+ foreach( $required_fields as $slug => $field ) {
417
+ if ( !$this->field_has_error( $slug ) && empty( $_POST[ 'rtb-' . $slug ] ) ) {
418
+ $this->validation_errors[] = array(
419
+ 'field' => $slug,
420
+ 'post_variable' => '',
421
+ 'message' => __( 'Please complete this field to request a booking.', 'restaurant-reservations' ),
422
+ );
423
+ }
424
+ }
425
 
426
  do_action( 'rtb_validate_booking_submission', $this );
427
 
429
 
430
  /**
431
  * Check if submission is valid
432
+ *
433
  * @since 0.0.1
434
  */
435
  public function is_valid_submission() {
436
+
437
  if ( !count( $this->validation_errors ) ) {
438
  return true;
439
  }
440
+
441
+ return false;
442
+ }
443
+
444
+ /**
445
+ * Check if a field already has an error attached to it
446
+ *
447
+ * @field string Field slug
448
+ * @since 1.3
449
+ */
450
+ public function field_has_error( $field_slug ) {
451
+
452
+ foreach( $this->validation_errors as $error ) {
453
+ if ( $error['field'] == $field_slug ) {
454
+ return true;
455
+ }
456
+ }
457
+
458
  return false;
459
  }
460
 
469
  'post_title' => $this->name,
470
  'post_content' => $this->message,
471
  'post_date' => $this->date,
472
+ 'post_status' => $this->status,
473
  );
474
 
475
+ if ( !empty( $this->ID ) ) {
476
+ $args['ID'] = $this->ID;
477
+ }
478
+
479
  $args = apply_filters( 'rtb_insert_booking_data', $args, $this );
480
 
481
  $id = wp_insert_post( $args );
includes/Compatibility.class.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined( 'ABSPATH' ) ) exit;
3
+
4
+ if ( !class_exists( 'rtbCompatibility' ) ) {
5
+ /**
6
+ * Class to handle backwards compatibilty issues for Restaurant Reservations
7
+ *
8
+ * @since 1.3
9
+ */
10
+ class rtbCompatibility {
11
+
12
+ /**
13
+ * Set up hooks
14
+ */
15
+ public function __construct() {
16
+
17
+ // Preserve this defined constant in case anyone relied on it
18
+ // to check if the plugin was active
19
+ define( 'RTB_TEXTDOMAIN', 'rtbdomain' );
20
+
21
+ // Load a .mo file for an old textdomain if one exists
22
+ add_filter( 'load_textdomain_mofile', array( $this, 'load_old_textdomain' ), 10, 2 );
23
+
24
+ }
25
+
26
+ /**
27
+ * Load a .mo file for an old textdomain if one exists
28
+ *
29
+ * In versions prior to 1.3, the textdomain did not match the plugin
30
+ * slug. This had to be changed to comply with upcoming changes to
31
+ * how translations are managed in the .org repo. This function
32
+ * checks to see if an old translation file exists and loads it if
33
+ * it does, so that people don't lose their translations.
34
+ *
35
+ * Old textdomain: rtbdomain
36
+ */
37
+ public function load_old_textdomain( $mofile, $textdomain ) {
38
+
39
+ if ( $textdomain === 'restaurant-reservations' && 0 === strpos( $mofile, WP_LANG_DIR . '/plugins/' ) && !file_exists( $mofile ) ) {
40
+ $mofile = dirname( $mofile ) . DIRECTORY_SEPARATOR . str_replace( $textdomain, 'rtbdomain', basename( $mofile ) );
41
+ }
42
+
43
+ return $mofile;
44
+ }
45
+
46
+ }
47
+ } // endif
includes/CustomPostTypes.class.php CHANGED
@@ -35,19 +35,19 @@ class rtbCustomPostTypes {
35
  // Define the booking custom post type
36
  $args = array(
37
  'labels' => array(
38
- 'name' => __( 'Bookings', RTB_TEXTDOMAIN ),
39
- 'singular_name' => __( 'Booking', RTB_TEXTDOMAIN ),
40
- 'menu_name' => __( 'Bookings', RTB_TEXTDOMAIN ),
41
- 'name_admin_bar' => __( 'Bookings', RTB_TEXTDOMAIN ),
42
- 'add_new' => __( 'Add New', RTB_TEXTDOMAIN ),
43
- 'add_new_item' => __( 'Add New Booking', RTB_TEXTDOMAIN ),
44
- 'edit_item' => __( 'Edit Booking', RTB_TEXTDOMAIN ),
45
- 'new_item' => __( 'New Booking', RTB_TEXTDOMAIN ),
46
- 'view_item' => __( 'View Booking', RTB_TEXTDOMAIN ),
47
- 'search_items' => __( 'Search Bookings', RTB_TEXTDOMAIN ),
48
- 'not_found' => __( 'No bookings found', RTB_TEXTDOMAIN ),
49
- 'not_found_in_trash' => __( 'No bookings found in trash', RTB_TEXTDOMAIN ),
50
- 'all_items' => __( 'All Bookings', RTB_TEXTDOMAIN ),
51
  ),
52
  'menu_icon' => 'dashicons-calendar',
53
  'public' => false,
@@ -77,31 +77,31 @@ class rtbCustomPostTypes {
77
  public function set_booking_statuses() {
78
 
79
  $this->booking_statuses['pending'] = array(
80
- 'label' => _x( 'Pending', 'Booking status when it is pending review', RTB_TEXTDOMAIN ),
81
  'default' => true, // Whether or not this status is part of WP Core
82
  'user_selectable' => true, // Whether or not a user can set a booking to this status
83
  );
84
 
85
  $this->booking_statuses['confirmed'] = array (
86
- 'label' => _x( 'Confirmed', 'Booking status for a confirmed booking', RTB_TEXTDOMAIN ),
87
  'default' => false, // Whether or not this status is part of WP Core
88
  'user_selectable' => true, // Whether or not a user can set a booking to this status
89
  'public' => false,
90
  'exclude_from_search' => true,
91
  'show_in_admin_all_list' => true,
92
  'show_in_admin_status_list' => true,
93
- 'label_count' => _n_noop( 'Confirmed <span class="count">(%s)</span>', 'Confirmed <span class="count">(%s)</span>', RTB_TEXTDOMAIN ),
94
  );
95
 
96
  $this->booking_statuses['closed'] = array(
97
- 'label' => _x( 'Closed', 'Booking status for a closed booking', RTB_TEXTDOMAIN ),
98
  'default' => false, // Whether or not this status is part of WP Core
99
  'user_selectable' => true, // Whether or not a user can set a booking to this status
100
  'public' => false,
101
  'exclude_from_search' => true,
102
  'show_in_admin_all_list' => true,
103
  'show_in_admin_status_list' => true,
104
- 'label_count' => _n_noop( 'Closed <span class="count">(%s)</span>', 'Closed <span class="count">(%s)</span>', RTB_TEXTDOMAIN )
105
  );
106
 
107
  // Let addons hook in to add/edit/remove post statuses
35
  // Define the booking custom post type
36
  $args = array(
37
  'labels' => array(
38
+ 'name' => __( 'Bookings', 'restaurant-reservations' ),
39
+ 'singular_name' => __( 'Booking', 'restaurant-reservations' ),
40
+ 'menu_name' => __( 'Bookings', 'restaurant-reservations' ),
41
+ 'name_admin_bar' => __( 'Bookings', 'restaurant-reservations' ),
42
+ 'add_new' => __( 'Add New', 'restaurant-reservations' ),
43
+ 'add_new_item' => __( 'Add New Booking', 'restaurant-reservations' ),
44
+ 'edit_item' => __( 'Edit Booking', 'restaurant-reservations' ),
45
+ 'new_item' => __( 'New Booking', 'restaurant-reservations' ),
46
+ 'view_item' => __( 'View Booking', 'restaurant-reservations' ),
47
+ 'search_items' => __( 'Search Bookings', 'restaurant-reservations' ),
48
+ 'not_found' => __( 'No bookings found', 'restaurant-reservations' ),
49
+ 'not_found_in_trash' => __( 'No bookings found in trash', 'restaurant-reservations' ),
50
+ 'all_items' => __( 'All Bookings', 'restaurant-reservations' ),
51
  ),
52
  'menu_icon' => 'dashicons-calendar',
53
  'public' => false,
77
  public function set_booking_statuses() {
78
 
79
  $this->booking_statuses['pending'] = array(
80
+ 'label' => _x( 'Pending', 'Booking status when it is pending review', 'restaurant-reservations' ),
81
  'default' => true, // Whether or not this status is part of WP Core
82
  'user_selectable' => true, // Whether or not a user can set a booking to this status
83
  );
84
 
85
  $this->booking_statuses['confirmed'] = array (
86
+ 'label' => _x( 'Confirmed', 'Booking status for a confirmed booking', 'restaurant-reservations' ),
87
  'default' => false, // Whether or not this status is part of WP Core
88
  'user_selectable' => true, // Whether or not a user can set a booking to this status
89
  'public' => false,
90
  'exclude_from_search' => true,
91
  'show_in_admin_all_list' => true,
92
  'show_in_admin_status_list' => true,
93
+ 'label_count' => _n_noop( 'Confirmed <span class="count">(%s)</span>', 'Confirmed <span class="count">(%s)</span>', 'restaurant-reservations' ),
94
  );
95
 
96
  $this->booking_statuses['closed'] = array(
97
+ 'label' => _x( 'Closed', 'Booking status for a closed booking', 'restaurant-reservations' ),
98
  'default' => false, // Whether or not this status is part of WP Core
99
  'user_selectable' => true, // Whether or not a user can set a booking to this status
100
  'public' => false,
101
  'exclude_from_search' => true,
102
  'show_in_admin_all_list' => true,
103
  'show_in_admin_status_list' => true,
104
+ 'label_count' => _n_noop( 'Closed <span class="count">(%s)</span>', 'Closed <span class="count">(%s)</span>', 'restaurant-reservations' )
105
  );
106
 
107
  // Let addons hook in to add/edit/remove post statuses
includes/Notification.Email.class.php CHANGED
@@ -83,13 +83,15 @@ class rtbNotificationEmail extends rtbNotification {
83
  public function set_to_email() {
84
 
85
  if ( $this->target == 'user' ) {
86
- $this->to_email = empty( $this->booking->email ) ? null : $this->booking->email;
87
 
88
  } else {
89
  global $rtb_controller;
90
- $this->to_email = $rtb_controller->settings->get_setting( 'admin-email-address' );
91
  }
92
 
 
 
93
  }
94
 
95
  /**
@@ -101,13 +103,16 @@ class rtbNotificationEmail extends rtbNotification {
101
  global $rtb_controller;
102
 
103
  if ( $this->target == 'user' ) {
104
- $this->from_email = $rtb_controller->settings->get_setting( 'reply-to-address' );
105
- $this->from_name = $rtb_controller->settings->get_setting( 'reply-to-name' );
106
  } else {
107
- $this->from_email = $this->booking->email;
108
- $this->from_name = $this->booking->name;
109
  }
110
 
 
 
 
111
  }
112
 
113
  /**
@@ -120,18 +125,22 @@ class rtbNotificationEmail extends rtbNotification {
120
 
121
  if( $this->event == 'new_submission' ) {
122
  if ( $this->target == 'admin' ) {
123
- $this->subject = $this->process_subject_template( $rtb_controller->settings->get_setting( 'subject-booking-admin' ) );
124
  } elseif ( $this->target == 'user' ) {
125
- $this->subject = $this->process_subject_template( $rtb_controller->settings->get_setting( 'subject-booking-user' ) );
126
  }
127
 
128
  } elseif ( $this->event == 'pending_to_confirmed' ) {
129
- $this->subject = $this->process_subject_template( $rtb_controller->settings->get_setting( 'subject-confirmed-user' ) );
130
 
131
  } elseif ( $this->event == 'pending_to_closed' ) {
132
- $this->subject = $this->process_subject_template( $rtb_controller->settings->get_setting( 'subject-rejected-user' ) );
 
 
133
  }
134
 
 
 
135
  }
136
 
137
  /**
@@ -145,6 +154,7 @@ class rtbNotificationEmail extends rtbNotification {
145
  $headers = "From: " . stripslashes_deep( html_entity_decode( $rtb_controller->settings->get_setting( 'reply-to-name' ), ENT_COMPAT, 'UTF-8' ) ) . " <" . apply_filters( 'rtb_notification_email_header_from_email', get_option( 'admin_email' ) ) . ">\r\n";
146
  $headers .= "Reply-To: " . stripslashes_deep( html_entity_decode( $this->from_name, ENT_COMPAT, 'UTF-8' ) ) . " <" . $this->from_email . ">\r\n";
147
  $headers .= "Content-Type: text/html; charset=utf-8\r\n";
 
148
  $this->headers = apply_filters( 'rtb_notification_email_headers', $headers, $this );
149
 
150
  }
@@ -159,26 +169,30 @@ class rtbNotificationEmail extends rtbNotification {
159
 
160
  if ( $this->event == 'new_submission' ) {
161
  if ( $this->target == 'user' ) {
162
- $template = 'template-booking-user';
163
  } elseif ( $this->target == 'admin' ) {
164
- $template = 'template-booking-admin';
165
  }
166
 
167
  } elseif ( $this->event == 'pending_to_confirmed' ) {
168
  if ( $this->target == 'user' ) {
169
- $template = 'template-confirmed-user';
170
  }
171
 
172
  } elseif ( $this->event == 'pending_to_closed' ) {
173
  if ( $this->target == 'user' ) {
174
- $template = 'template-rejected-user';
175
  }
 
 
176
  }
177
 
178
- if ( !isset( $template ) ) {
 
 
179
  $this->message = '';
180
  } else {
181
- $this->message = wpautop( $this->process_template( $this->get_template( $template ) ) );
182
  }
183
 
184
  }
83
  public function set_to_email() {
84
 
85
  if ( $this->target == 'user' ) {
86
+ $to_email = empty( $this->booking->email ) ? null : $this->booking->email;
87
 
88
  } else {
89
  global $rtb_controller;
90
+ $to_email = $rtb_controller->settings->get_setting( 'admin-email-address' );
91
  }
92
 
93
+ $this->to_email = apply_filters( 'rtb_notification_email_to_email', $to_email, $this );
94
+
95
  }
96
 
97
  /**
103
  global $rtb_controller;
104
 
105
  if ( $this->target == 'user' ) {
106
+ $from_email = $rtb_controller->settings->get_setting( 'reply-to-address' );
107
+ $from_name = $rtb_controller->settings->get_setting( 'reply-to-name' );
108
  } else {
109
+ $from_email = $this->booking->email;
110
+ $from_name = $this->booking->name;
111
  }
112
 
113
+ $this->from_email = apply_filters( 'rtb_notification_email_from_email', $from_email, $this );
114
+ $this->from_name = apply_filters( 'rtb_notification_email_from_name', $from_name, $this );
115
+
116
  }
117
 
118
  /**
125
 
126
  if( $this->event == 'new_submission' ) {
127
  if ( $this->target == 'admin' ) {
128
+ $subject = $rtb_controller->settings->get_setting( 'subject-booking-admin' );
129
  } elseif ( $this->target == 'user' ) {
130
+ $subject = $rtb_controller->settings->get_setting( 'subject-booking-user' );
131
  }
132
 
133
  } elseif ( $this->event == 'pending_to_confirmed' ) {
134
+ $subject = $rtb_controller->settings->get_setting( 'subject-confirmed-user' );
135
 
136
  } elseif ( $this->event == 'pending_to_closed' ) {
137
+ $subject = $rtb_controller->settings->get_setting( 'subject-rejected-user' );
138
+ } else {
139
+ $subject = '';
140
  }
141
 
142
+ $this->subject = $this->process_subject_template( apply_filters( 'rtb_notification_email_subject', $subject, $this ) );
143
+
144
  }
145
 
146
  /**
154
  $headers = "From: " . stripslashes_deep( html_entity_decode( $rtb_controller->settings->get_setting( 'reply-to-name' ), ENT_COMPAT, 'UTF-8' ) ) . " <" . apply_filters( 'rtb_notification_email_header_from_email', get_option( 'admin_email' ) ) . ">\r\n";
155
  $headers .= "Reply-To: " . stripslashes_deep( html_entity_decode( $this->from_name, ENT_COMPAT, 'UTF-8' ) ) . " <" . $this->from_email . ">\r\n";
156
  $headers .= "Content-Type: text/html; charset=utf-8\r\n";
157
+
158
  $this->headers = apply_filters( 'rtb_notification_email_headers', $headers, $this );
159
 
160
  }
169
 
170
  if ( $this->event == 'new_submission' ) {
171
  if ( $this->target == 'user' ) {
172
+ $template = $this->get_template( 'template-booking-user' );
173
  } elseif ( $this->target == 'admin' ) {
174
+ $template = $this->get_template( 'template-booking-admin' );
175
  }
176
 
177
  } elseif ( $this->event == 'pending_to_confirmed' ) {
178
  if ( $this->target == 'user' ) {
179
+ $template = $this->get_template( 'template-confirmed-user' );
180
  }
181
 
182
  } elseif ( $this->event == 'pending_to_closed' ) {
183
  if ( $this->target == 'user' ) {
184
+ $template = $this->get_template( 'template-rejected-user' );
185
  }
186
+ } else {
187
+ $template = '';
188
  }
189
 
190
+ $template = apply_filters( 'rtb_notification_email_template', $template, $this );
191
+
192
+ if ( empty( $template ) ) {
193
  $this->message = '';
194
  } else {
195
+ $this->message = wpautop( $this->process_template( $template ) );
196
  }
197
 
198
  }
includes/Notification.class.php CHANGED
@@ -85,9 +85,9 @@ abstract class rtbNotification {
85
  '{date}' => $this->booking->format_date( $this->booking->date ),
86
  '{phone}' => $this->booking->phone,
87
  '{message}' => $this->booking->message,
88
- '{bookings_link}' => '<a href="' . admin_url( 'admin.php?page=rtb-bookings&status=pending' ) . '">' . __( 'View pending bookings', RTB_TEXTDOMAIN ) . '</a>',
89
- '{confirm_link}' => '<a href="' . admin_url( 'admin.php?page=rtb-bookings&rtb-quicklink=confirm&booking=' . esc_attr( $this->booking->ID ) ) . '">' . __( 'Confirm this booking', RTB_TEXTDOMAIN ) . '</a>',
90
- '{close_link}' => '<a href="' . admin_url( 'admin.php?page=rtb-bookings&rtb-quicklink=close&booking=' . esc_attr( $this->booking->ID ) ) . '">' . __( 'Reject this booking', RTB_TEXTDOMAIN ) . '</a>',
91
  '{site_name}' => get_bloginfo( 'name' ),
92
  '{site_link}' => '<a href="' . home_url( '/' ) . '">' . get_bloginfo( 'name' ) . '</a>',
93
  '{current_time}' => date( get_option( 'date_format' ), current_time( 'timestamp' ) ) . ' ' . date( get_option( 'time_format' ), current_time( 'timestamp' ) ),
85
  '{date}' => $this->booking->format_date( $this->booking->date ),
86
  '{phone}' => $this->booking->phone,
87
  '{message}' => $this->booking->message,
88
+ '{bookings_link}' => '<a href="' . admin_url( 'admin.php?page=rtb-bookings&status=pending' ) . '">' . __( 'View pending bookings', 'restaurant-reservations' ) . '</a>',
89
+ '{confirm_link}' => '<a href="' . admin_url( 'admin.php?page=rtb-bookings&rtb-quicklink=confirm&booking=' . esc_attr( $this->booking->ID ) ) . '">' . __( 'Confirm this booking', 'restaurant-reservations' ) . '</a>',
90
+ '{close_link}' => '<a href="' . admin_url( 'admin.php?page=rtb-bookings&rtb-quicklink=close&booking=' . esc_attr( $this->booking->ID ) ) . '">' . __( 'Reject this booking', 'restaurant-reservations' ) . '</a>',
91
  '{site_name}' => get_bloginfo( 'name' ),
92
  '{site_link}' => '<a href="' . home_url( '/' ) . '">' . get_bloginfo( 'name' ) . '</a>',
93
  '{current_time}' => date( get_option( 'date_format' ), current_time( 'timestamp' ) ) . ' ' . date( get_option( 'time_format' ), current_time( 'timestamp' ) ),
includes/Notifications.class.php CHANGED
@@ -29,23 +29,21 @@ class rtbNotifications {
29
  public $notifications;
30
 
31
  /**
32
- * Hooks to execute notifications on
33
- *
34
- * Post Status Transitions and other hooks.
35
- * See: http://codex.wordpress.org/Post_Status_Transitions
36
- *
37
- * @var array
38
  * @since 0.0.1
39
  */
40
- public $hooks;
 
 
41
 
42
  /**
43
- * Set up notifications
44
  * @since 0.0.1
45
  */
46
- public function __construct() {
47
 
48
- // Hook into all status changes that require notifications
49
  $hooks = array(
50
  'rtb_insert_booking' => array( $this, 'new_submission' ), // Booking submitted
51
  'pending_to_confirmed' => array( $this, 'pending_to_confirmed' ), // Booking confirmed
@@ -59,15 +57,6 @@ class rtbNotifications {
59
  }
60
 
61
  // Register notifications
62
- add_action( 'init', array( $this, 'register_notifications' ) );
63
- }
64
-
65
- /**
66
- * Register notifications
67
- * @since 0.0.1
68
- */
69
- public function register_notifications() {
70
-
71
  require_once( RTB_PLUGIN_DIR . '/includes/Notification.class.php' );
72
  require_once( RTB_PLUGIN_DIR . '/includes/Notification.Email.class.php' );
73
 
@@ -109,10 +98,16 @@ class rtbNotifications {
109
  return;
110
  }
111
 
112
- $this->booking = $booking;
113
-
114
- $this->event( 'new_submission' );
 
115
 
 
 
 
 
 
116
  }
117
 
118
  /**
29
  public $notifications;
30
 
31
  /**
32
+ * Register notifications hook early so that other early hooks can
33
+ * be used by the notification system.
 
 
 
 
34
  * @since 0.0.1
35
  */
36
+ public function __construct() {
37
+ add_action( 'init', array( $this, 'register_notifications' ) );
38
+ }
39
 
40
  /**
41
+ * Register notifications
42
  * @since 0.0.1
43
  */
44
+ public function register_notifications() {
45
 
46
+ // Hook into all events that require notifications
47
  $hooks = array(
48
  'rtb_insert_booking' => array( $this, 'new_submission' ), // Booking submitted
49
  'pending_to_confirmed' => array( $this, 'pending_to_confirmed' ), // Booking confirmed
57
  }
58
 
59
  // Register notifications
 
 
 
 
 
 
 
 
 
60
  require_once( RTB_PLUGIN_DIR . '/includes/Notification.class.php' );
61
  require_once( RTB_PLUGIN_DIR . '/includes/Notification.Email.class.php' );
62
 
98
  return;
99
  }
100
 
101
+ // If the post status is not pending, trigger a post status
102
+ // transition as though it's gone from pending_to_{status}
103
+ if ( $booking->status != 'pending' ) {
104
+ do_action( 'pending_to_' . $booking->status, get_post( $booking->ID ) );
105
 
106
+ // Otherwise proceed with the new_submission event
107
+ } else {
108
+ $this->booking = $booking;
109
+ $this->event( 'new_submission' );
110
+ }
111
  }
112
 
113
  /**
includes/Settings.class.php CHANGED
@@ -80,10 +80,10 @@ class rtbSettings {
80
 
81
  $this->defaults = array(
82
 
83
- 'success-message' => _x( 'Thanks, your booking request is waiting to be confirmed. Updates will be sent to the email address you provided.', RTB_TEXTDOMAIN ),
84
- 'date-format' => _x( 'mmmm d, yyyy', 'Default date format for display. Must match formatting rules at http://amsul.ca/pickadate.js/date.htm#formatting-rules', RTB_TEXTDOMAIN ),
85
- 'time-format' => _x( 'h:i A', 'Default time format for display. Must match formatting rules at http://amsul.ca/pickadate.js/time.htm#formats', RTB_TEXTDOMAIN ),
86
- 'time-interval' => _x( '30', 'Default interval in minutes when selecting a time.', RTB_TEXTDOMAIN ),
87
 
88
  // Email address where admin notifications should be sent
89
  'admin-email-address' => get_option( 'admin_email' ),
@@ -93,7 +93,7 @@ class rtbSettings {
93
  'reply-to-address' => get_option( 'admin_email' ),
94
 
95
  // Email template sent to an admin when a new booking request is made
96
- 'subject-booking-admin' => _x( 'New Booking Request', 'Default email subject for admin notifications of new bookings', RTB_TEXTDOMAIN ),
97
  'template-booking-admin' => _x( 'A new booking request has been made at {site_name}:
98
 
99
  {user_name}
@@ -108,11 +108,11 @@ class rtbSettings {
108
 
109
  <em>This message was sent by {site_link} on {current_time}.</em>',
110
  'Default email sent to the admin when a new booking request is made. The tags in {brackets} will be replaced by the appropriate content and should be left in place. HTML is allowed, but be aware that many email clients do not handle HTML very well.',
111
- RTB_TEXTDOMAIN
112
  ),
113
 
114
  // Email template sent to a user when a new booking request is made
115
- 'subject-booking-user' => sprintf( _x( 'Your booking at %s is pending', 'Default email subject sent to user when they request a booking. %s will be replaced by the website name', RTB_TEXTDOMAIN ), get_bloginfo( 'name' ) ),
116
  'template-booking-user' => _x( 'Thanks {user_name},
117
 
118
  Your booking request is <strong>waiting to be confirmed</strong>.
@@ -128,11 +128,11 @@ Give us a few moments to make sure that we\'ve got space for you. You will recei
128
 
129
  <em>This message was sent by {site_link} on {current_time}.</em>',
130
  'Default email sent to users when they make a new booking request. The tags in {brackets} will be replaced by the appropriate content and should be left in place. HTML is allowed, but be aware that many email clients do not handle HTML very well.',
131
- RTB_TEXTDOMAIN
132
  ),
133
 
134
  // Email template sent to a user when a booking request is confirmed
135
- 'subject-confirmed-user' => sprintf( _x( 'Your booking at %s is confirmed', 'Default email subject sent to user when their booking is confirmed. %s will be replaced by the website name', RTB_TEXTDOMAIN ), get_bloginfo( 'name' ) ),
136
  'template-confirmed-user' => _x( 'Hi {user_name},
137
 
138
  Your booking request has been <strong>confirmed</strong>. We look forward to seeing you soon.
@@ -146,11 +146,11 @@ Your booking request has been <strong>confirmed</strong>. We look forward to see
146
 
147
  <em>This message was sent by {site_link} on {current_time}.</em>',
148
  'Default email sent to users when they make a new booking request. The tags in {brackets} will be replaced by the appropriate content and should be left in place. HTML is allowed, but be aware that many email clients do not handle HTML very well.',
149
- RTB_TEXTDOMAIN
150
  ),
151
 
152
  // Email template sent to a user when a booking request is rejected
153
- 'subject-rejected-user' => sprintf( _x( 'Your booking at %s was not accepted', 'Default email subject sent to user when their booking is rejected. %s will be replaced by the website name', RTB_TEXTDOMAIN ), get_bloginfo( 'name' ) ),
154
  'template-rejected-user' => _x( 'Hi {user_name},
155
 
156
  Sorry, we could not accomodate your booking request. We\'re full or not open at the time you requested:
@@ -163,7 +163,7 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
163
 
164
  <em>This message was sent by {site_link} on {current_time}.</em>',
165
  'Default email sent to users when they make a new booking request. The tags in {brackets} will be replaced by the appropriate content and should be left in place. HTML is allowed, but be aware that many email clients do not handle HTML very well.',
166
- RTB_TEXTDOMAIN
167
  ),
168
  );
169
 
@@ -186,14 +186,14 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
186
  }
187
 
188
  if ( !empty( $this->settings[ $setting ] ) ) {
189
- return $this->settings[ $setting ];
190
  }
191
 
192
  if ( !empty( $this->defaults[ $setting ] ) ) {
193
- return $this->defaults[ $setting ];
194
  }
195
 
196
- return null;
197
  }
198
 
199
  /**
@@ -206,7 +206,7 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
206
  require_once( RTB_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php' );
207
  $sap = sap_initialize_library(
208
  $args = array(
209
- 'version' => '2.0.a.7',
210
  'lib_url' => RTB_PLUGIN_URL . '/lib/simple-admin-pages/',
211
  )
212
  );
@@ -215,8 +215,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
215
  'submenu',
216
  array(
217
  'id' => 'rtb-settings',
218
- 'title' => __( 'Settings', RTB_TEXTDOMAIN ),
219
- 'menu_title' => __( 'Settings', RTB_TEXTDOMAIN ),
220
  'parent_menu' => 'rtb-bookings',
221
  'description' => '',
222
  'capability' => 'manage_options',
@@ -228,7 +228,7 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
228
  'rtb-settings',
229
  array(
230
  'id' => 'rtb-general',
231
- 'title' => __( 'General', RTB_TEXTDOMAIN ),
232
  'is_tab' => true,
233
  )
234
  );
@@ -239,8 +239,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
239
  'post',
240
  array(
241
  'id' => 'booking-page',
242
- 'title' => __( 'Booking Page', RTB_TEXTDOMAIN ),
243
- 'description' => __( 'Select a page on your site to automatically display the booking form and confirmation message.', RTB_TEXTDOMAIN ),
244
  'blank_option' => true,
245
  'args' => array(
246
  'post_type' => 'page',
@@ -253,12 +253,13 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
253
  $sap->add_setting(
254
  'rtb-settings',
255
  'rtb-general',
256
- 'text',
257
  array(
258
  'id' => 'party-size',
259
- 'title' => __( 'Max Party Size', RTB_TEXTDOMAIN ),
260
- 'description' => __( 'Set a maximum allowed party size for bookings. Leave it empty to allow parties of any size.', RTB_TEXTDOMAIN ),
261
- 'placeholder' => __( 'No limit', RTB_TEXTDOMAIN ),
 
262
  )
263
  );
264
 
@@ -268,8 +269,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
268
  'textarea',
269
  array(
270
  'id' => 'success-message',
271
- 'title' => __( 'Success Message', RTB_TEXTDOMAIN ),
272
- 'description' => __( 'Enter the message to display when a booking request is made.', RTB_TEXTDOMAIN ),
273
  'placeholder' => $this->defaults['success-message'],
274
  )
275
  );
@@ -280,8 +281,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
280
  'text',
281
  array(
282
  'id' => 'date-format',
283
- 'title' => __( 'Date Format', RTB_TEXTDOMAIN ),
284
- 'description' => __( 'Define how the date should appear after it has been selected. <a href="http://amsul.ca/pickadate.js/date.htm#formatting-rules">Formatting rules</a>', RTB_TEXTDOMAIN ),
285
  'placeholder' => $this->defaults['date-format'],
286
  )
287
  );
@@ -292,8 +293,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
292
  'text',
293
  array(
294
  'id' => 'time-format',
295
- 'title' => __( 'Time Format', RTB_TEXTDOMAIN ),
296
- 'description' => __( 'Define how the time should appear after it has been selected. <a href="http://amsul.ca/pickadate.js/time.htm#formatting-rules">Formatting rules</a>', RTB_TEXTDOMAIN ),
297
  'placeholder' => $this->defaults['time-format'],
298
  )
299
  );
@@ -306,8 +307,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
306
  'select',
307
  array(
308
  'id' => 'i8n',
309
- 'title' => __( 'Language', RTB_TEXTDOMAIN ),
310
- 'description' => __( 'Select a language to use for the booking form datepicker if it is different than your WordPress language setting.', RTB_TEXTDOMAIN ),
311
  'options' => $this->supported_i8n,
312
  )
313
  );
@@ -317,50 +318,77 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
317
  'rtb-settings',
318
  array(
319
  'id' => 'rtb-schedule',
320
- 'title' => __( 'Booking Schedule', RTB_TEXTDOMAIN ),
321
  'is_tab' => true,
322
  )
323
  );
324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  $sap->add_setting(
326
  'rtb-settings',
327
  'rtb-schedule',
328
  'scheduler',
329
  array(
330
  'id' => 'schedule-open',
331
- 'title' => __( 'Schedule', RTB_TEXTDOMAIN ),
332
- 'description' => __( 'Define the weekly schedule during which you accept bookings.', RTB_TEXTDOMAIN ),
333
  'weekdays' => array(
334
- 'monday' => _x( 'Mo', 'Monday abbreviation', RTB_TEXTDOMAIN ),
335
- 'tuesday' => _x( 'Tu', 'Tuesday abbreviation', RTB_TEXTDOMAIN ),
336
- 'wednesday' => _x( 'We', 'Wednesday abbreviation', RTB_TEXTDOMAIN ),
337
- 'thursday' => _x( 'Th', 'Thursday abbreviation', RTB_TEXTDOMAIN ),
338
- 'friday' => _x( 'Fr', 'Friday abbreviation', RTB_TEXTDOMAIN ),
339
- 'saturday' => _x( 'Sa', 'Saturday abbreviation', RTB_TEXTDOMAIN ),
340
- 'sunday' => _x( 'Su', 'Sunday abbreviation', RTB_TEXTDOMAIN )
341
  ),
342
  'time_format' => $this->get_setting( 'time-format' ),
343
  'date_format' => $this->get_setting( 'date-format' ),
344
  'disable_weeks' => true,
345
  'disable_date' => true,
 
346
  )
347
  );
348
 
 
349
  $sap->add_setting(
350
  'rtb-settings',
351
  'rtb-schedule',
352
  'scheduler',
353
  array(
354
  'id' => 'schedule-closed',
355
- 'title' => __( 'Exceptions', RTB_TEXTDOMAIN ),
356
- 'description' => __( "Define special opening hours for holidays, events or other needs. Leave the time empty if you're closed all day.", RTB_TEXTDOMAIN ),
357
  'time_format' => $this->get_setting( 'time-format' ),
358
  'date_format' => $this->get_setting( 'date-format' ),
359
  'disable_weekdays' => true,
360
  'disable_weeks' => true,
361
- 'instance_schedule_summaries' => array(
362
- 'all_day' => _x( 'Closed all day', 'Brief description of a scheduling exception when no times are set', SAP_TEXTDOMAIN ),
363
- ),
364
  )
365
  );
366
 
@@ -370,16 +398,16 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
370
  'select',
371
  array(
372
  'id' => 'early-bookings',
373
- 'title' => __( 'Early Bookings', RTB_TEXTDOMAIN ),
374
- 'description' => __( 'Select how early customers can make their booking.', RTB_TEXTDOMAIN ),
375
  'blank_option' => false,
376
  'options' => array(
377
- '' => __( 'Any time', RTB_TEXTDOMAIN ),
378
- '1' => __( 'Up to 1 day in advance', RTB_TEXTDOMAIN ),
379
- '7' => __( 'Up to 1 week in advance', RTB_TEXTDOMAIN ),
380
- '14' => __( 'Up to 2 weeks in advance', RTB_TEXTDOMAIN ),
381
- '30' => __( 'Up to 30 days in advance', RTB_TEXTDOMAIN ),
382
- '90' => __( 'Up to 90 days in advance', RTB_TEXTDOMAIN ),
383
  )
384
  )
385
  );
@@ -390,17 +418,17 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
390
  'select',
391
  array(
392
  'id' => 'late-bookings',
393
- 'title' => __( 'Late Bookings', RTB_TEXTDOMAIN ),
394
- 'description' => __( 'Select how late customers can make their booking.', RTB_TEXTDOMAIN ),
395
  'blank_option' => false,
396
  'options' => array(
397
- '' => __( 'Up to the last minute', RTB_TEXTDOMAIN ),
398
- '15' => __( 'At least 15 minutes in advance', RTB_TEXTDOMAIN ),
399
- '30' => __( 'At least 30 minutes in advance', RTB_TEXTDOMAIN ),
400
- '45' => __( 'At least 45 minutes in advance', RTB_TEXTDOMAIN ),
401
- '60' => __( 'At least 1 hour in advance', RTB_TEXTDOMAIN ),
402
- '240' => __( 'At least 4 hours in advance', RTB_TEXTDOMAIN ),
403
- '1440' => __( 'At least 1 day in advance', RTB_TEXTDOMAIN ),
404
  )
405
  )
406
  );
@@ -411,13 +439,13 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
411
  'select',
412
  array(
413
  'id' => 'date-onload',
414
- 'title' => __( 'Date Pre-selection', RTB_TEXTDOMAIN ),
415
- 'description' => __( 'When the booking form is loaded, should it automatically attempt to select a valid date?', RTB_TEXTDOMAIN ),
416
  'blank_option' => false,
417
  'options' => array(
418
- '' => __( 'Select today if valid', RTB_TEXTDOMAIN ),
419
- 'soonest' => __( 'Select today or next valid date', RTB_TEXTDOMAIN ),
420
- 'empty' => __( 'Leave empty', RTB_TEXTDOMAIN ),
421
  )
422
  )
423
  );
@@ -428,14 +456,14 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
428
  'select',
429
  array(
430
  'id' => 'time-interval',
431
- 'title' => __( 'Time Interval', RTB_TEXTDOMAIN ),
432
- 'description' => __( 'Select the number of minutes between each available time.', RTB_TEXTDOMAIN ),
433
  'blank_option' => false,
434
  'options' => array(
435
- '' => __( 'Every 30 minutes', RTB_TEXTDOMAIN ),
436
- '15' => __( 'Every 15 minutes', RTB_TEXTDOMAIN ),
437
- '10' => __( 'Every 10 minutes', RTB_TEXTDOMAIN ),
438
- '5' => __( 'Every 5 minutes', RTB_TEXTDOMAIN ),
439
  )
440
  )
441
  );
@@ -444,7 +472,7 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
444
  'rtb-settings',
445
  array(
446
  'id' => 'rtb-notifications',
447
- 'title' => __( 'Notifications', RTB_TEXTDOMAIN ),
448
  'is_tab' => true,
449
  )
450
  );
@@ -455,8 +483,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
455
  'text',
456
  array(
457
  'id' => 'reply-to-name',
458
- 'title' => __( 'Reply-To Name', RTB_TEXTDOMAIN ),
459
- 'description' => __( 'The name which should appear in the Reply-To field of a user notification email', RTB_TEXTDOMAIN ),
460
  'placeholder' => $this->defaults['reply-to-name'],
461
  )
462
  );
@@ -467,8 +495,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
467
  'text',
468
  array(
469
  'id' => 'reply-to-address',
470
- 'title' => __( 'Reply-To Email Address', RTB_TEXTDOMAIN ),
471
- 'description' => __( 'The email address which should appear in the Reply-To field of a user notification email.', RTB_TEXTDOMAIN ),
472
  'placeholder' => $this->defaults['reply-to-address'],
473
  )
474
  );
@@ -479,8 +507,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
479
  'toggle',
480
  array(
481
  'id' => 'admin-email-option',
482
- 'title' => __( 'Admin Notification', RTB_TEXTDOMAIN ),
483
- 'label' => __( 'Send an email notification to an administrator when a new booking is requested.', RTB_TEXTDOMAIN )
484
  )
485
  );
486
 
@@ -490,8 +518,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
490
  'text',
491
  array(
492
  'id' => 'admin-email-address',
493
- 'title' => __( 'Admin Email Address', RTB_TEXTDOMAIN ),
494
- 'description' => __( 'The email address where admin notifications should be sent.', RTB_TEXTDOMAIN ),
495
  'placeholder' => $this->defaults['admin-email-address'],
496
  )
497
  );
@@ -500,9 +528,9 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
500
  'rtb-settings',
501
  array(
502
  'id' => 'rtb-notifications-templates',
503
- 'title' => __( 'Email Templates', RTB_TEXTDOMAIN ),
504
  'tab' => 'rtb-notifications',
505
- 'description' => 'Adjust the messages that are emailed to users and admins during the booking process.',
506
  )
507
  );
508
 
@@ -512,9 +540,9 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
512
  'html',
513
  array(
514
  'id' => 'template-tags-description',
515
- 'title' => __( 'Template Tags', RTB_TEXTDOMAIN ),
516
  'html' => '
517
- <p class="description">' . __( 'Use the following tags to automatically add booking information to the emails. Tags labeled with an asterisk (*) can be used in the email subject as well.', RTB_TEXTDOMAIN ) . '</p>' .
518
  $this->render_template_tag_descriptions(),
519
  )
520
  );
@@ -525,8 +553,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
525
  'text',
526
  array(
527
  'id' => 'subject-booking-admin',
528
- 'title' => __( 'Admin Notification Subject', RTB_TEXTDOMAIN ),
529
- 'description' => __( 'The email subject for admin notifications.', RTB_TEXTDOMAIN ),
530
  'placeholder' => $this->defaults['subject-booking-admin'],
531
  )
532
  );
@@ -537,8 +565,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
537
  'editor',
538
  array(
539
  'id' => 'template-booking-admin',
540
- 'title' => __( 'Admin Notification Email', RTB_TEXTDOMAIN ),
541
- 'description' => __( 'Enter the email an admin should receive when an initial booking request is made.', RTB_TEXTDOMAIN ),
542
  'default' => $this->defaults['template-booking-admin'],
543
  )
544
  );
@@ -549,8 +577,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
549
  'text',
550
  array(
551
  'id' => 'subject-booking-user',
552
- 'title' => __( 'New Request Email Subject', RTB_TEXTDOMAIN ),
553
- 'description' => __( 'The email subject a user should receive when they make an initial booking request.', RTB_TEXTDOMAIN ),
554
  'placeholder' => $this->defaults['subject-booking-user'],
555
  )
556
  );
@@ -561,8 +589,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
561
  'editor',
562
  array(
563
  'id' => 'template-booking-user',
564
- 'title' => __( 'New Request Email', RTB_TEXTDOMAIN ),
565
- 'description' => __( 'Enter the email a user should receive when they make an initial booking request.', RTB_TEXTDOMAIN ),
566
  'default' => $this->defaults['template-booking-user'],
567
  )
568
  );
@@ -573,8 +601,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
573
  'text',
574
  array(
575
  'id' => 'subject-confirmed-user',
576
- 'title' => __( 'Confirmed Email Subject', RTB_TEXTDOMAIN ),
577
- 'description' => __( 'The email subject a user should receive when their booking has been confirmed.', RTB_TEXTDOMAIN ),
578
  'placeholder' => $this->defaults['subject-confirmed-user'],
579
  )
580
  );
@@ -585,8 +613,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
585
  'editor',
586
  array(
587
  'id' => 'template-confirmed-user',
588
- 'title' => __( 'Confirmed Email', RTB_TEXTDOMAIN ),
589
- 'description' => __( 'Enter the email a user should receive when their booking has been confirmed.', RTB_TEXTDOMAIN ),
590
  'default' => $this->defaults['template-confirmed-user'],
591
  )
592
  );
@@ -597,8 +625,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
597
  'text',
598
  array(
599
  'id' => 'subject-rejected-user',
600
- 'title' => __( 'Rejected Email Subject', RTB_TEXTDOMAIN ),
601
- 'description' => __( 'The email subject a user should receive when their booking has been rejected.', RTB_TEXTDOMAIN ),
602
  'placeholder' => $this->defaults['subject-rejected-user'],
603
  )
604
  );
@@ -609,8 +637,8 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
609
  'editor',
610
  array(
611
  'id' => 'template-rejected-user',
612
- 'title' => __( 'Rejected Email', RTB_TEXTDOMAIN ),
613
- 'description' => __( 'Enter the email a user should receive when their booking has been rejected.', RTB_TEXTDOMAIN ),
614
  'default' => $this->defaults['template-rejected-user'],
615
  )
616
  );
@@ -621,6 +649,194 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
621
 
622
  }
623
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
624
  /**
625
  * Render HTML code of descriptions for the template tags
626
  * @since 1.2.3
@@ -628,18 +844,18 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
628
  public function render_template_tag_descriptions() {
629
 
630
  $descriptions = apply_filters( 'rtb_notification_template_tag_descriptions', array(
631
- '{user_email}' => __( 'Email of the user who made the booking', RTB_TEXTDOMAIN ),
632
- '{user_name}' => __( '* Name of the user who made the booking', RTB_TEXTDOMAIN ),
633
- '{party}' => __( '* Number of people booked', RTB_TEXTDOMAIN ),
634
- '{date}' => __( '* Date and time of the booking', RTB_TEXTDOMAIN ),
635
- '{phone}' => __( 'Phone number if supplied with the request', RTB_TEXTDOMAIN ),
636
- '{message}' => __( 'Message added to the request', RTB_TEXTDOMAIN ),
637
- '{bookings_link}' => __( 'A link to the admin panel showing pending bookings', RTB_TEXTDOMAIN ),
638
- '{confirm_link}' => __( 'A link to confirm this booking. Only include this in admin notifications', RTB_TEXTDOMAIN ),
639
- '{close_link}' => __( 'A link to reject this booking. Only include this in admin notifications', RTB_TEXTDOMAIN ),
640
- '{site_name}' => __( 'The name of this website', RTB_TEXTDOMAIN ),
641
- '{site_link}' => __( 'A link to this website', RTB_TEXTDOMAIN ),
642
- '{current_time}' => __( 'Current date and time', RTB_TEXTDOMAIN ),
643
  )
644
  );
645
 
80
 
81
  $this->defaults = array(
82
 
83
+ 'success-message' => _x( 'Thanks, your booking request is waiting to be confirmed. Updates will be sent to the email address you provided.', 'restaurant-reservations' ),
84
+ 'date-format' => _x( 'mmmm d, yyyy', 'Default date format for display. Must match formatting rules at http://amsul.ca/pickadate.js/date.htm#formatting-rules', 'restaurant-reservations' ),
85
+ 'time-format' => _x( 'h:i A', 'Default time format for display. Must match formatting rules at http://amsul.ca/pickadate.js/time.htm#formats', 'restaurant-reservations' ),
86
+ 'time-interval' => _x( '30', 'Default interval in minutes when selecting a time.', 'restaurant-reservations' ),
87
 
88
  // Email address where admin notifications should be sent
89
  'admin-email-address' => get_option( 'admin_email' ),
93
  'reply-to-address' => get_option( 'admin_email' ),
94
 
95
  // Email template sent to an admin when a new booking request is made
96
+ 'subject-booking-admin' => _x( 'New Booking Request', 'Default email subject for admin notifications of new bookings', 'restaurant-reservations' ),
97
  'template-booking-admin' => _x( 'A new booking request has been made at {site_name}:
98
 
99
  {user_name}
108
 
109
  <em>This message was sent by {site_link} on {current_time}.</em>',
110
  'Default email sent to the admin when a new booking request is made. The tags in {brackets} will be replaced by the appropriate content and should be left in place. HTML is allowed, but be aware that many email clients do not handle HTML very well.',
111
+ 'restaurant-reservations'
112
  ),
113
 
114
  // Email template sent to a user when a new booking request is made
115
+ 'subject-booking-user' => sprintf( _x( 'Your booking at %s is pending', 'Default email subject sent to user when they request a booking. %s will be replaced by the website name', 'restaurant-reservations' ), get_bloginfo( 'name' ) ),
116
  'template-booking-user' => _x( 'Thanks {user_name},
117
 
118
  Your booking request is <strong>waiting to be confirmed</strong>.
128
 
129
  <em>This message was sent by {site_link} on {current_time}.</em>',
130
  'Default email sent to users when they make a new booking request. The tags in {brackets} will be replaced by the appropriate content and should be left in place. HTML is allowed, but be aware that many email clients do not handle HTML very well.',
131
+ 'restaurant-reservations'
132
  ),
133
 
134
  // Email template sent to a user when a booking request is confirmed
135
+ 'subject-confirmed-user' => sprintf( _x( 'Your booking at %s is confirmed', 'Default email subject sent to user when their booking is confirmed. %s will be replaced by the website name', 'restaurant-reservations' ), get_bloginfo( 'name' ) ),
136
  'template-confirmed-user' => _x( 'Hi {user_name},
137
 
138
  Your booking request has been <strong>confirmed</strong>. We look forward to seeing you soon.
146
 
147
  <em>This message was sent by {site_link} on {current_time}.</em>',
148
  'Default email sent to users when they make a new booking request. The tags in {brackets} will be replaced by the appropriate content and should be left in place. HTML is allowed, but be aware that many email clients do not handle HTML very well.',
149
+ 'restaurant-reservations'
150
  ),
151
 
152
  // Email template sent to a user when a booking request is rejected
153
+ 'subject-rejected-user' => sprintf( _x( 'Your booking at %s was not accepted', 'Default email subject sent to user when their booking is rejected. %s will be replaced by the website name', 'restaurant-reservations' ), get_bloginfo( 'name' ) ),
154
  'template-rejected-user' => _x( 'Hi {user_name},
155
 
156
  Sorry, we could not accomodate your booking request. We\'re full or not open at the time you requested:
163
 
164
  <em>This message was sent by {site_link} on {current_time}.</em>',
165
  'Default email sent to users when they make a new booking request. The tags in {brackets} will be replaced by the appropriate content and should be left in place. HTML is allowed, but be aware that many email clients do not handle HTML very well.',
166
+ 'restaurant-reservations'
167
  ),
168
  );
169
 
186
  }
187
 
188
  if ( !empty( $this->settings[ $setting ] ) ) {
189
+ return apply_filters( 'rtb-setting-' . $setting, $this->settings[ $setting ] );
190
  }
191
 
192
  if ( !empty( $this->defaults[ $setting ] ) ) {
193
+ return apply_filters( 'rtb-setting-' . $setting, $this->defaults[ $setting ] );
194
  }
195
 
196
+ return apply_filters( 'rtb-setting-' . $setting, null );
197
  }
198
 
199
  /**
206
  require_once( RTB_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php' );
207
  $sap = sap_initialize_library(
208
  $args = array(
209
+ 'version' => '2.0.a.8',
210
  'lib_url' => RTB_PLUGIN_URL . '/lib/simple-admin-pages/',
211
  )
212
  );
215
  'submenu',
216
  array(
217
  'id' => 'rtb-settings',
218
+ 'title' => __( 'Settings', 'restaurant-reservations' ),
219
+ 'menu_title' => __( 'Settings', 'restaurant-reservations' ),
220
  'parent_menu' => 'rtb-bookings',
221
  'description' => '',
222
  'capability' => 'manage_options',
228
  'rtb-settings',
229
  array(
230
  'id' => 'rtb-general',
231
+ 'title' => __( 'General', 'restaurant-reservations' ),
232
  'is_tab' => true,
233
  )
234
  );
239
  'post',
240
  array(
241
  'id' => 'booking-page',
242
+ 'title' => __( 'Booking Page', 'restaurant-reservations' ),
243
+ 'description' => __( 'Select a page on your site to automatically display the booking form and confirmation message.', 'restaurant-reservations' ),
244
  'blank_option' => true,
245
  'args' => array(
246
  'post_type' => 'page',
253
  $sap->add_setting(
254
  'rtb-settings',
255
  'rtb-general',
256
+ 'select',
257
  array(
258
  'id' => 'party-size',
259
+ 'title' => __( 'Max Party Size', 'restaurant-reservations' ),
260
+ 'description' => __( 'Set a maximum allowed party size for bookings.', 'restaurant-reservations' ),
261
+ 'blank_option' => false,
262
+ 'options' => $this->get_party_size_setting_options(),
263
  )
264
  );
265
 
269
  'textarea',
270
  array(
271
  'id' => 'success-message',
272
+ 'title' => __( 'Success Message', 'restaurant-reservations' ),
273
+ 'description' => __( 'Enter the message to display when a booking request is made.', 'restaurant-reservations' ),
274
  'placeholder' => $this->defaults['success-message'],
275
  )
276
  );
281
  'text',
282
  array(
283
  'id' => 'date-format',
284
+ 'title' => __( 'Date Format', 'restaurant-reservations' ),
285
+ 'description' => sprintf( __( 'Define how the date is formatted on the booking form. %sFormatting rules%s. This only changes the format on the booking form. To change the date format in notification messages, modify your general %sWordPress Settings%s.', 'restaurant-reservations' ), '<a href="http://amsul.ca/pickadate.js/date.htm#formatting-rules">', '</a>', '<a href="' . admin_url( 'options-general.php' ) . '">', '</a>' ),
286
  'placeholder' => $this->defaults['date-format'],
287
  )
288
  );
293
  'text',
294
  array(
295
  'id' => 'time-format',
296
+ 'title' => __( 'Time Format', 'restaurant-reservations' ),
297
+ 'description' => sprintf( __( 'Define how the time is formatted on the booking form. %sFormatting rules%s. This only changes the format on the booking form. To change the time format in notification messages, modify your general %sWordPress Settings%s.', 'restaurant-reservations' ), '<a href="http://amsul.ca/pickadate.js/time.htm#formatting-rules">', '</a>', '<a href="' . admin_url( 'options-general.php' ) . '">', '</a>' ),
298
  'placeholder' => $this->defaults['time-format'],
299
  )
300
  );
307
  'select',
308
  array(
309
  'id' => 'i8n',
310
+ 'title' => __( 'Language', 'restaurant-reservations' ),
311
+ 'description' => __( 'Select a language to use for the booking form datepicker if it is different than your WordPress language setting.', 'restaurant-reservations' ),
312
  'options' => $this->supported_i8n,
313
  )
314
  );
318
  'rtb-settings',
319
  array(
320
  'id' => 'rtb-schedule',
321
+ 'title' => __( 'Booking Schedule', 'restaurant-reservations' ),
322
  'is_tab' => true,
323
  )
324
  );
325
 
326
+ // Translateable strings for scheduler components
327
+ $scheduler_strings = array(
328
+ 'add_rule' => __( 'Add new scheduling rule', 'restaurant-reservations' ),
329
+ 'weekly' => _x( 'Weekly', 'Format of a scheduling rule', 'restaurant-reservations' ),
330
+ 'monthly' => _x( 'Monthly', 'Format of a scheduling rule', 'restaurant-reservations' ),
331
+ 'date' => _x( 'Date', 'Format of a scheduling rule', 'restaurant-reservations' ),
332
+ 'weekdays' => _x( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', 'restaurant-reservations' ),
333
+ 'month_weeks' => _x( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', 'restaurant-reservations' ),
334
+ 'date_label' => _x( 'Date', 'Label to select a date for a scheduling rule', 'restaurant-reservations' ),
335
+ 'time_label' => _x( 'Time', 'Label to select a time slot for a scheduling rule', 'restaurant-reservations' ),
336
+ 'allday' => _x( 'All day', 'Label to set a scheduling rule to last all day', 'restaurant-reservations' ),
337
+ 'start' => _x( 'Start', 'Label for the starting time of a scheduling rule', 'restaurant-reservations' ),
338
+ 'end' => _x( 'End', 'Label for the ending time of a scheduling rule', 'restaurant-reservations' ),
339
+ 'set_time_prompt' => _x( 'All day long. Want to %sset a time slot%s?', 'Prompt displayed when a scheduling rule is set without any time restrictions', 'restaurant-reservations' ),
340
+ 'toggle' => _x( 'Open and close this rule', 'Toggle a scheduling rule open and closed', 'restaurant-reservations' ),
341
+ 'delete' => _x( 'Delete rule', 'Delete a scheduling rule', 'restaurant-reservations' ),
342
+ 'delete_schedule' => __( 'Delete scheduling rule', 'restaurant-reservations' ),
343
+ 'never' => _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'restaurant-reservations' ),
344
+ 'weekly_always' => _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'restaurant-reservations' ),
345
+ 'monthly_weekdays' => _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'restaurant-reservations' ),
346
+ 'monthly_weeks' => _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'restaurant-reservations' ),
347
+ 'all_day' => _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'restaurant-reservations' ),
348
+ 'before' => _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm', 'restaurant-reservations' ),
349
+ 'after' => _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm', 'restaurant-reservations' ),
350
+ 'separator' => _x( '&mdash;', 'Separator between times of a scheduling rule', 'restaurant-reservations' ),
351
+ );
352
+
353
  $sap->add_setting(
354
  'rtb-settings',
355
  'rtb-schedule',
356
  'scheduler',
357
  array(
358
  'id' => 'schedule-open',
359
+ 'title' => __( 'Schedule', 'restaurant-reservations' ),
360
+ 'description' => __( 'Define the weekly schedule during which you accept bookings.', 'restaurant-reservations' ),
361
  'weekdays' => array(
362
+ 'monday' => _x( 'Mo', 'Monday abbreviation', 'restaurant-reservations' ),
363
+ 'tuesday' => _x( 'Tu', 'Tuesday abbreviation', 'restaurant-reservations' ),
364
+ 'wednesday' => _x( 'We', 'Wednesday abbreviation', 'restaurant-reservations' ),
365
+ 'thursday' => _x( 'Th', 'Thursday abbreviation', 'restaurant-reservations' ),
366
+ 'friday' => _x( 'Fr', 'Friday abbreviation', 'restaurant-reservations' ),
367
+ 'saturday' => _x( 'Sa', 'Saturday abbreviation', 'restaurant-reservations' ),
368
+ 'sunday' => _x( 'Su', 'Sunday abbreviation', 'restaurant-reservations' )
369
  ),
370
  'time_format' => $this->get_setting( 'time-format' ),
371
  'date_format' => $this->get_setting( 'date-format' ),
372
  'disable_weeks' => true,
373
  'disable_date' => true,
374
+ 'strings' => $scheduler_strings,
375
  )
376
  );
377
 
378
+ $scheduler_strings['all_day'] = _x( 'Closed all day', 'Brief default description of a scheduling exception when no times are set', 'restaurant-reservations' );
379
  $sap->add_setting(
380
  'rtb-settings',
381
  'rtb-schedule',
382
  'scheduler',
383
  array(
384
  'id' => 'schedule-closed',
385
+ 'title' => __( 'Exceptions', 'restaurant-reservations' ),
386
+ 'description' => __( "Define special opening hours for holidays, events or other needs. Leave the time empty if you're closed all day.", 'restaurant-reservations' ),
387
  'time_format' => $this->get_setting( 'time-format' ),
388
  'date_format' => $this->get_setting( 'date-format' ),
389
  'disable_weekdays' => true,
390
  'disable_weeks' => true,
391
+ 'strings' => $scheduler_strings,
 
 
392
  )
393
  );
394
 
398
  'select',
399
  array(
400
  'id' => 'early-bookings',
401
+ 'title' => __( 'Early Bookings', 'restaurant-reservations' ),
402
+ 'description' => __( 'Select how early customers can make their booking.', 'restaurant-reservations' ),
403
  'blank_option' => false,
404
  'options' => array(
405
+ '' => __( 'Any time', 'restaurant-reservations' ),
406
+ '1' => __( 'Up to 1 day in advance', 'restaurant-reservations' ),
407
+ '7' => __( 'Up to 1 week in advance', 'restaurant-reservations' ),
408
+ '14' => __( 'Up to 2 weeks in advance', 'restaurant-reservations' ),
409
+ '30' => __( 'Up to 30 days in advance', 'restaurant-reservations' ),
410
+ '90' => __( 'Up to 90 days in advance', 'restaurant-reservations' ),
411
  )
412
  )
413
  );
418
  'select',
419
  array(
420
  'id' => 'late-bookings',
421
+ 'title' => __( 'Late Bookings', 'restaurant-reservations' ),
422
+ 'description' => __( 'Select how late customers can make their booking.', 'restaurant-reservations' ),
423
  'blank_option' => false,
424
  'options' => array(
425
+ '' => __( 'Up to the last minute', 'restaurant-reservations' ),
426
+ '15' => __( 'At least 15 minutes in advance', 'restaurant-reservations' ),
427
+ '30' => __( 'At least 30 minutes in advance', 'restaurant-reservations' ),
428
+ '45' => __( 'At least 45 minutes in advance', 'restaurant-reservations' ),
429
+ '60' => __( 'At least 1 hour in advance', 'restaurant-reservations' ),
430
+ '240' => __( 'At least 4 hours in advance', 'restaurant-reservations' ),
431
+ '1440' => __( 'At least 1 day in advance', 'restaurant-reservations' ),
432
  )
433
  )
434
  );
439
  'select',
440
  array(
441
  'id' => 'date-onload',
442
+ 'title' => __( 'Date Pre-selection', 'restaurant-reservations' ),
443
+ 'description' => __( 'When the booking form is loaded, should it automatically attempt to select a valid date?', 'restaurant-reservations' ),
444
  'blank_option' => false,
445
  'options' => array(
446
+ '' => __( 'Select today if valid', 'restaurant-reservations' ),
447
+ 'soonest' => __( 'Select today or next valid date', 'restaurant-reservations' ),
448
+ 'empty' => __( 'Leave empty', 'restaurant-reservations' ),
449
  )
450
  )
451
  );
456
  'select',
457
  array(
458
  'id' => 'time-interval',
459
+ 'title' => __( 'Time Interval', 'restaurant-reservations' ),
460
+ 'description' => __( 'Select the number of minutes between each available time.', 'restaurant-reservations' ),
461
  'blank_option' => false,
462
  'options' => array(
463
+ '' => __( 'Every 30 minutes', 'restaurant-reservations' ),
464
+ '15' => __( 'Every 15 minutes', 'restaurant-reservations' ),
465
+ '10' => __( 'Every 10 minutes', 'restaurant-reservations' ),
466
+ '5' => __( 'Every 5 minutes', 'restaurant-reservations' ),
467
  )
468
  )
469
  );
472
  'rtb-settings',
473
  array(
474
  'id' => 'rtb-notifications',
475
+ 'title' => __( 'Notifications', 'restaurant-reservations' ),
476
  'is_tab' => true,
477
  )
478
  );
483
  'text',
484
  array(
485
  'id' => 'reply-to-name',
486
+ 'title' => __( 'Reply-To Name', 'restaurant-reservations' ),
487
+ 'description' => __( 'The name which should appear in the Reply-To field of a user notification email', 'restaurant-reservations' ),
488
  'placeholder' => $this->defaults['reply-to-name'],
489
  )
490
  );
495
  'text',
496
  array(
497
  'id' => 'reply-to-address',
498
+ 'title' => __( 'Reply-To Email Address', 'restaurant-reservations' ),
499
+ 'description' => __( 'The email address which should appear in the Reply-To field of a user notification email.', 'restaurant-reservations' ),
500
  'placeholder' => $this->defaults['reply-to-address'],
501
  )
502
  );
507
  'toggle',
508
  array(
509
  'id' => 'admin-email-option',
510
+ 'title' => __( 'Admin Notification', 'restaurant-reservations' ),
511
+ 'label' => __( 'Send an email notification to an administrator when a new booking is requested.', 'restaurant-reservations' )
512
  )
513
  );
514
 
518
  'text',
519
  array(
520
  'id' => 'admin-email-address',
521
+ 'title' => __( 'Admin Email Address', 'restaurant-reservations' ),
522
+ 'description' => __( 'The email address where admin notifications should be sent.', 'restaurant-reservations' ),
523
  'placeholder' => $this->defaults['admin-email-address'],
524
  )
525
  );
528
  'rtb-settings',
529
  array(
530
  'id' => 'rtb-notifications-templates',
531
+ 'title' => __( 'Email Templates', 'restaurant-reservations' ),
532
  'tab' => 'rtb-notifications',
533
+ 'description' => __( 'Adjust the messages that are emailed to users and admins during the booking process.', 'restaurant-reservations' ),
534
  )
535
  );
536
 
540
  'html',
541
  array(
542
  'id' => 'template-tags-description',
543
+ 'title' => __( 'Template Tags', 'restaurant-reservations' ),
544
  'html' => '
545
+ <p class="description">' . __( 'Use the following tags to automatically add booking information to the emails. Tags labeled with an asterisk (*) can be used in the email subject as well.', 'restaurant-reservations' ) . '</p>' .
546
  $this->render_template_tag_descriptions(),
547
  )
548
  );
553
  'text',
554
  array(
555
  'id' => 'subject-booking-admin',
556
+ 'title' => __( 'Admin Notification Subject', 'restaurant-reservations' ),
557
+ 'description' => __( 'The email subject for admin notifications.', 'restaurant-reservations' ),
558
  'placeholder' => $this->defaults['subject-booking-admin'],
559
  )
560
  );
565
  'editor',
566
  array(
567
  'id' => 'template-booking-admin',
568
+ 'title' => __( 'Admin Notification Email', 'restaurant-reservations' ),
569
+ 'description' => __( 'Enter the email an admin should receive when an initial booking request is made.', 'restaurant-reservations' ),
570
  'default' => $this->defaults['template-booking-admin'],
571
  )
572
  );
577
  'text',
578
  array(
579
  'id' => 'subject-booking-user',
580
+ 'title' => __( 'New Request Email Subject', 'restaurant-reservations' ),
581
+ 'description' => __( 'The email subject a user should receive when they make an initial booking request.', 'restaurant-reservations' ),
582
  'placeholder' => $this->defaults['subject-booking-user'],
583
  )
584
  );
589
  'editor',
590
  array(
591
  'id' => 'template-booking-user',
592
+ 'title' => __( 'New Request Email', 'restaurant-reservations' ),
593
+ 'description' => __( 'Enter the email a user should receive when they make an initial booking request.', 'restaurant-reservations' ),
594
  'default' => $this->defaults['template-booking-user'],
595
  )
596
  );
601
  'text',
602
  array(
603
  'id' => 'subject-confirmed-user',
604
+ 'title' => __( 'Confirmed Email Subject', 'restaurant-reservations' ),
605
+ 'description' => __( 'The email subject a user should receive when their booking has been confirmed.', 'restaurant-reservations' ),
606
  'placeholder' => $this->defaults['subject-confirmed-user'],
607
  )
608
  );
613
  'editor',
614
  array(
615
  'id' => 'template-confirmed-user',
616
+ 'title' => __( 'Confirmed Email', 'restaurant-reservations' ),
617
+ 'description' => __( 'Enter the email a user should receive when their booking has been confirmed.', 'restaurant-reservations' ),
618
  'default' => $this->defaults['template-confirmed-user'],
619
  )
620
  );
625
  'text',
626
  array(
627
  'id' => 'subject-rejected-user',
628
+ 'title' => __( 'Rejected Email Subject', 'restaurant-reservations' ),
629
+ 'description' => __( 'The email subject a user should receive when their booking has been rejected.', 'restaurant-reservations' ),
630
  'placeholder' => $this->defaults['subject-rejected-user'],
631
  )
632
  );
637
  'editor',
638
  array(
639
  'id' => 'template-rejected-user',
640
+ 'title' => __( 'Rejected Email', 'restaurant-reservations' ),
641
+ 'description' => __( 'Enter the email a user should receive when their booking has been rejected.', 'restaurant-reservations' ),
642
  'default' => $this->defaults['template-rejected-user'],
643
  )
644
  );
649
 
650
  }
651
 
652
+ /**
653
+ * Get options for the party size setting
654
+ * @since 1.3
655
+ */
656
+ public function get_party_size_setting_options() {
657
+
658
+ $options = array(
659
+ '' => __( 'Any size', 'restaurant-reservations' ),
660
+ );
661
+
662
+ $max = apply_filters( 'rtb_party_size_upper_limit', 100 );
663
+
664
+ for ( $i = 1; $i <= $max; $i++ ) {
665
+ $options[$i] = $i;
666
+ }
667
+
668
+ return apply_filters( 'rtb_party_size_setting_options', $options );
669
+ }
670
+
671
+ /**
672
+ * Get options for the party select field in the booking form
673
+ * @since 1.3
674
+ */
675
+ public function get_form_party_options() {
676
+
677
+ $party_size = (int) $this->get_setting( 'party-size' );
678
+
679
+ $max = empty( $party_size ) ? apply_filters( 'rtb_party_size_upper_limit', 100 ) : (int) $this->get_setting( 'party-size' );
680
+
681
+ for ( $i = 1; $i <= $max; $i++ ) {
682
+ $options[$i] = $i;
683
+ }
684
+
685
+ return apply_filters( 'rtb_form_party_options', $options );
686
+ }
687
+
688
+ /**
689
+ * Retrieve form fields
690
+ * @since 1.3
691
+ */
692
+ public function get_booking_form_fields( $request = null ) {
693
+
694
+ // $request will represent a rtbBooking object with the request
695
+ // details when the form is being printed and $_POST data exists
696
+ // to populate the request. All other times $request will just
697
+ // be an empty object
698
+ if ( $request === null ) {
699
+ global $rtb_controller;
700
+ $request = $rtb_controller->request;
701
+ }
702
+
703
+ /**
704
+ * This array defines the field details and a callback function to
705
+ * render each field. To customize the form output, modify the
706
+ * callback functions to point to your custom function. Don't forget
707
+ * to output an error message in your custom callback function. You
708
+ * can use rtb_print_form_error( $slug ) to do this.
709
+ *
710
+ * In addition to the parameters described below, each fieldset
711
+ * and field can accept a `classes` array in the callback args since
712
+ * v1.3. These classes will be appended to the <fieldset> and
713
+ * <div> elements for each field. A fieldset can also take a
714
+ * `legend_classes` array in the callback_args which will be
715
+ * added to the legend element.
716
+ *
717
+ * Example:
718
+ *
719
+ * $fields = array(
720
+ * 'fieldset' => array(
721
+ * 'legend' => __( 'My Legend', 'restaurant-reservations' ),
722
+ * 'callback_args' => array(
723
+ * 'classes' => array( 'fieldset-class', 'other-fieldset-class' ),
724
+ * 'legend_classes => array( 'legend-class' ),
725
+ * ),
726
+ * 'fields' => array(
727
+ * 'my-field' => array(
728
+ * ...
729
+ * 'callback_args' => array(
730
+ * 'classes' => array( 'field-class' ),
731
+ * )
732
+ * )
733
+ * )
734
+ * )
735
+ * );
736
+ *
737
+ * See /includes/template-functions.php
738
+ */
739
+ $fields = array(
740
+
741
+ // Reservation details fieldset
742
+ 'reservation' => array(
743
+ 'legend' => __( 'Book a table', 'restaurant-reservations' ),
744
+ 'fields' => array(
745
+ 'date' => array(
746
+ 'title' => __( 'Date', 'restaurant-reservations' ),
747
+ 'request_input' => empty( $request->request_date ) ? '' : $request->request_date,
748
+ 'callback' => 'rtb_print_form_text_field',
749
+ 'required' => true,
750
+ ),
751
+ 'time' => array(
752
+ 'title' => __( 'Time', 'restaurant-reservations' ),
753
+ 'request_input' => empty( $request->request_time ) ? '' : $request->request_time,
754
+ 'callback' => 'rtb_print_form_text_field',
755
+ 'required' => true,
756
+ ),
757
+ 'party' => array(
758
+ 'title' => __( 'Party', 'restaurant-reservations' ),
759
+ 'request_input' => empty( $request->party ) ? '' : $request->party,
760
+ 'callback' => 'rtb_print_form_select_field',
761
+ 'callback_args' => array(
762
+ 'options' => $this->get_form_party_options(),
763
+ ),
764
+ 'required' => true,
765
+ ),
766
+ ),
767
+ ),
768
+
769
+ // Contact details fieldset
770
+ 'contact' => array(
771
+ 'legend' => __( 'Contact Details', 'restaurant-reservations' ),
772
+ 'fields' => array(
773
+ 'name' => array(
774
+ 'title' => __( 'Name', 'restaurant-reservations' ),
775
+ 'request_input' => empty( $request->name ) ? '' : $request->name,
776
+ 'callback' => 'rtb_print_form_text_field',
777
+ 'required' => true,
778
+ ),
779
+ 'email' => array(
780
+ 'title' => __( 'Email', 'restaurant-reservations' ),
781
+ 'request_input' => empty( $request->email ) ? '' : $request->email,
782
+ 'callback' => 'rtb_print_form_text_field',
783
+ 'callback_args' => array(
784
+ 'input_type' => 'email',
785
+ ),
786
+ 'required' => true,
787
+ ),
788
+ 'phone' => array(
789
+ 'title' => __( 'Phone', 'restaurant-reservations' ),
790
+ 'request_input' => empty( $request->phone ) ? '' : $request->phone,
791
+ 'callback' => 'rtb_print_form_text_field',
792
+ 'callback_args' => array(
793
+ 'input_type' => 'tel',
794
+ ),
795
+ ),
796
+ 'add-message' => array(
797
+ 'title' => __( 'Add a Message', 'restaurant-reservations' ),
798
+ 'request_input' => '',
799
+ 'callback' => 'rtb_print_form_message_link',
800
+ ),
801
+ 'message' => array(
802
+ 'title' => __( 'Message', 'restaurant-reservations' ),
803
+ 'request_input' => empty( $request->message ) ? '' : $request->message,
804
+ 'callback' => 'rtb_print_form_textarea_field',
805
+ ),
806
+ ),
807
+ ),
808
+ );
809
+
810
+ return apply_filters( 'rtb_booking_form_fields', $fields, $request );
811
+ }
812
+
813
+ /**
814
+ * Get required fields
815
+ *
816
+ * Filters the fields array to return just those marked required
817
+ * @since 1.3
818
+ */
819
+ public function get_required_fields() {
820
+
821
+ $required_fields = array();
822
+
823
+ $fieldsets = $this->get_booking_form_fields();
824
+ foreach ( $fieldsets as $fieldset ) {
825
+ $required_fields = array_merge( $required_fields, array_filter( $fieldset['fields'], array( $this, 'is_field_required' ) ) );
826
+ }
827
+
828
+ return $required_fields;
829
+ }
830
+
831
+ /**
832
+ * Check if a field is required
833
+ *
834
+ * @since 1.3
835
+ */
836
+ public function is_field_required( $field ) {
837
+ return !empty( $field['required'] );
838
+ }
839
+
840
  /**
841
  * Render HTML code of descriptions for the template tags
842
  * @since 1.2.3
844
  public function render_template_tag_descriptions() {
845
 
846
  $descriptions = apply_filters( 'rtb_notification_template_tag_descriptions', array(
847
+ '{user_email}' => __( 'Email of the user who made the booking', 'restaurant-reservations' ),
848
+ '{user_name}' => __( '* Name of the user who made the booking', 'restaurant-reservations' ),
849
+ '{party}' => __( '* Number of people booked', 'restaurant-reservations' ),
850
+ '{date}' => __( '* Date and time of the booking', 'restaurant-reservations' ),
851
+ '{phone}' => __( 'Phone number if supplied with the request', 'restaurant-reservations' ),
852
+ '{message}' => __( 'Message added to the request', 'restaurant-reservations' ),
853
+ '{bookings_link}' => __( 'A link to the admin panel showing pending bookings', 'restaurant-reservations' ),
854
+ '{confirm_link}' => __( 'A link to confirm this booking. Only include this in admin notifications', 'restaurant-reservations' ),
855
+ '{close_link}' => __( 'A link to reject this booking. Only include this in admin notifications', 'restaurant-reservations' ),
856
+ '{site_name}' => __( 'The name of this website', 'restaurant-reservations' ),
857
+ '{site_link}' => __( 'A link to this website', 'restaurant-reservations' ),
858
+ '{current_time}' => __( 'Current date and time', 'restaurant-reservations' ),
859
  )
860
  );
861
 
includes/WP_List_Table.BookingsTable.class.php CHANGED
@@ -72,8 +72,8 @@ class rtbBookingsTable extends WP_List_Table {
72
 
73
  // Set parent defaults
74
  parent::__construct( array(
75
- 'singular' => __( 'Booking', RTB_TEXTDOMAIN ),
76
- 'plural' => __( 'Bookings', RTB_TEXTDOMAIN ),
77
  'ajax' => false
78
  ) );
79
 
@@ -127,6 +127,20 @@ class rtbBookingsTable extends WP_List_Table {
127
  }
128
  }
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  /**
131
  * Strip unwanted query vars from the query string or ensure the correct
132
  * vars are passed around and those we don't want to preserve are discarded.
@@ -169,15 +183,13 @@ class rtbBookingsTable extends WP_List_Table {
169
  $schedule_query_string = remove_query_arg( array( 'schedule', 'start-date', 'end-date' ), $this->query_string );
170
 
171
  $views = array(
172
- 'all' => sprintf( '<a href="%s"%s>%s</a>', $schedule_query_string, $schedule == '' ? ' class="current"' : '', __( 'All', RTB_TEXTDOMAIN ) ),
173
- 'today' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'schedule' => 'today', 'paged' => FALSE ), $schedule_query_string ), $schedule === 'today' ? ' class="current"' : '', __( 'Today', RTB_TEXTDOMAIN ) ),
174
- 'upcoming' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'schedule' => 'upcoming', 'paged' => FALSE ), remove_query_arg( array( 'order' ), $schedule_query_string ) ), $schedule === 'upcoming' ? ' class="current"' : '', __( 'Upcoming', RTB_TEXTDOMAIN ) ),
175
  );
176
 
177
  if ( $schedule == 'custom' ) {
178
- $start_date = !empty( $this->filter_start_date ) ? $this->filter_start_date : '*';
179
- $end_date = !empty( $this->filter_end_date ) ? $this->filter_end_date : '*';
180
- $views['custom'] = '<span class="current">' . $start_date . _x( '&mdash;', 'Separator between two dates in a date range', RTB_TEXTDOMAIN ) . $end_date . '</span>';
181
  }
182
 
183
  $views = apply_filters( 'rtn_bookings_table_views_schedule', $views );
@@ -189,13 +201,13 @@ class rtbBookingsTable extends WP_List_Table {
189
  </ul>
190
 
191
  <div class="date-filters">
192
- <label for="start-date" class="screen-reader-text"><?php _e( 'Start Date:', RTB_TEXTDOMAIN ); ?></label>
193
- <input type="text" id="start-date" name="start-date" class="datepicker" value="<?php echo esc_attr( $this->filter_start_date ); ?>" placeholder="<?php _e( 'Start Date', RTB_TEXTDOMAIN ); ?>" />
194
- <label for="end-date" class="screen-reader-text"><?php _e( 'End Date:', RTB_TEXTDOMAIN ); ?></label>
195
- <input type="text" id="end-date" name="end-date" class="datepicker" value="<?php echo esc_attr( $this->filter_end_date ); ?>" placeholder="<?php _e( 'End Date', RTB_TEXTDOMAIN ); ?>" />
196
- <input type="submit" class="button-secondary" value="<?php _e( 'Apply', RTB_TEXTDOMAIN ); ?>"/>
197
  <?php if( !empty( $start_date ) || !empty( $end_date ) ) : ?>
198
- <a href="<?php echo add_query_arg( array( 'action' => 'clear_date_filters' ) ); ?>" class="button-secondary"><?php _e( 'Clear Filter', RTB_TEXTDOMAIN ); ?></a>
199
  <?php endif; ?>
200
  </div>
201
 
@@ -209,7 +221,7 @@ class rtbBookingsTable extends WP_List_Table {
209
  // email post meta as well or this search box could be
210
  // misleading for people who expect to search across all
211
  // visible data
212
- // $this->search_box( __( 'Search', RTB_TEXTDOMAIN ), 'rtb-bookings' );
213
  ?>
214
 
215
  <?php
@@ -225,18 +237,17 @@ class rtbBookingsTable extends WP_List_Table {
225
  /**
226
  * Retrieve the view types
227
  * @since 0.0.1
228
- * @todo it would be nice if the default view showed all upcoming pending + confirmed bookings, but not closed ones.
229
  */
230
  public function get_views() {
231
 
232
  $current = isset( $_GET['status'] ) ? $_GET['status'] : '';
233
 
234
  $views = array(
235
- 'all' => sprintf( '<a href="%s"%s>%s</a>', remove_query_arg( array( 'status', 'paged' ), $this->query_string ), $current === 'all' || $current == '' ? ' class="current"' : '', __( 'All', RTB_TEXTDOMAIN ) . ' <span class="count">(' . $this->booking_counts['total'] . ')</span>' ),
236
- 'pending' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'status' => 'pending', 'paged' => FALSE ), $this->query_string ), $current === 'pending' ? ' class="current"' : '', __( 'Pending', RTB_TEXTDOMAIN ) . ' <span class="count">(' . $this->booking_counts['pending'] . ')</span>' ),
237
- 'confirmed' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'status' => 'confirmed', 'paged' => FALSE ), $this->query_string ), $current === 'confirmed' ? ' class="current"' : '', __( 'Confirmed', RTB_TEXTDOMAIN ) . ' <span class="count">(' . $this->booking_counts['confirmed'] . ')</span>' ),
238
- 'closed' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'status' => 'closed', 'paged' => FALSE ), $this->query_string ), $current === 'closed' ? ' class="current"' : '', __( 'Closed', RTB_TEXTDOMAIN ) . ' <span class="count">(' . $this->booking_counts['closed'] . ')</span>' ),
239
- 'trash' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'status' => 'trash', 'paged' => FALSE ), $this->query_string ), $current === 'trash' ? ' class="current"' : '', __( 'Trash', RTB_TEXTDOMAIN ) . ' <span class="count">(' . $this->booking_counts['trash'] . ')</span>' ),
240
  );
241
 
242
  return apply_filters( 'rtb_bookings_table_views_status', $views );
@@ -246,7 +257,7 @@ class rtbBookingsTable extends WP_List_Table {
246
  * Generates content for a single row of the table
247
  * @since 0.0.1
248
  */
249
- function single_row( $item ) {
250
  static $row_class = '';
251
  $row_class = ( $row_class == '' ? 'alternate' : '' );
252
 
@@ -264,13 +275,13 @@ class rtbBookingsTable extends WP_List_Table {
264
  public function get_columns() {
265
  $columns = array(
266
  'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
267
- 'date' => __( 'Date', RTB_TEXTDOMAIN ),
268
- 'party' => __( 'Party', RTB_TEXTDOMAIN ),
269
- 'name' => __( 'Name', RTB_TEXTDOMAIN ),
270
- 'email' => __( 'Email', RTB_TEXTDOMAIN ),
271
- 'phone' => __( 'Phone', RTB_TEXTDOMAIN ),
272
- 'message' => __( 'Message', RTB_TEXTDOMAIN ),
273
- 'status' => __( 'Status', RTB_TEXTDOMAIN )
274
  );
275
 
276
  return apply_filters( 'rtb_bookings_table_columns', $columns );
@@ -296,6 +307,15 @@ class rtbBookingsTable extends WP_List_Table {
296
  switch ( $column_name ) {
297
  case 'date' :
298
  $value = $booking->format_date( $booking->date );
 
 
 
 
 
 
 
 
 
299
  break;
300
  case 'party' :
301
  $value = $booking->party;
@@ -321,7 +341,7 @@ class rtbBookingsTable extends WP_List_Table {
321
  if ( !empty( $rtb_controller->cpts->booking_statuses[$booking->post_status] ) ) {
322
  $value = $rtb_controller->cpts->booking_statuses[$booking->post_status]['label'];
323
  } elseif ( $booking->post_status == 'trash' ) {
324
- $value = _x( 'Trash', 'Status label for bookings put in the trash', RTB_TEXTDOMAIN );
325
  } else {
326
  $value = $booking->post_status;
327
  }
@@ -353,10 +373,10 @@ class rtbBookingsTable extends WP_List_Table {
353
  */
354
  public function get_bulk_actions() {
355
  $actions = array(
356
- 'delete' => __( 'Delete', RTB_TEXTDOMAIN ),
357
- 'set-status-confirmed' => __( 'Set To Confirmed', RTB_TEXTDOMAIN ),
358
- 'set-status-pending' => __( 'Set To Pending Review', RTB_TEXTDOMAIN ),
359
- 'set-status-closed' => __( 'Set To Closed', RTB_TEXTDOMAIN )
360
  );
361
 
362
  return apply_filters( 'rtb_bookings_table_bulk_actions', $actions );
@@ -471,16 +491,16 @@ class rtbBookingsTable extends WP_List_Table {
471
  <div id="rtb-admin-notice-bulk-<?php esc_attr( $this->last_action ); ?>" class="updated">
472
 
473
  <?php if ( $this->last_action == 'delete' ) : ?>
474
- <p><?php echo sprintf( _n( '%d booking deleted successfully.', '%d bookings deleted successfully.', $success, RTB_TEXTDOMAIN ), $success ); ?></p>
475
 
476
  <?php elseif ( $this->last_action == 'set-status-confirmed' ) : ?>
477
- <p><?php echo sprintf( _n( '%d booking confirmed.', '%d bookings confirmed.', $success, RTB_TEXTDOMAIN ), $success ); ?></p>
478
 
479
  <?php elseif ( $this->last_action == 'set-status-pending' ) : ?>
480
- <p><?php echo sprintf( _n( '%d booking set to pending.', '%d bookings set to pending.', $success, RTB_TEXTDOMAIN ), $success ); ?></p>
481
 
482
  <?php elseif ( $this->last_action == 'set-status-closed' ) : ?>
483
- <p><?php echo sprintf( _n( '%d booking closed.', '%d bookings closed.', $success, RTB_TEXTDOMAIN ), $success ); ?></p>
484
 
485
  <?php endif; ?>
486
  </div>
@@ -492,7 +512,7 @@ class rtbBookingsTable extends WP_List_Table {
492
  ?>
493
 
494
  <div id="rtb-admin-notice-bulk-<?php esc_attr( $this->last_action ); ?>" class="error">
495
- <p><?php echo sprintf( _n( '%d booking had errors and could not be processed.', '%d bookings had errors and could not be processed.', $failure, RTB_TEXTDOMAIN ), $failure ); ?></p>
496
  </div>
497
 
498
  <?php
@@ -520,14 +540,16 @@ class rtbBookingsTable extends WP_List_Table {
520
  $end_date = new DateTime( $this->filter_end_date );
521
  $where .= " AND p.post_date <= '" . $end_date->format( 'Y-m-d H:i:s' ) . "'";
522
  }
 
523
  } elseif ( !empty( $_GET['schedule'] ) ) {
524
 
525
  if ( $_GET['schedule'] == 'today' ) {
526
  $where .= " AND p.post_date >= '" . date( 'Y-m-d' ) . "' AND p.post_date <= '" . date( 'Y-m-d', current_time( 'timestamp' ) + 86400 ) . "'";
527
-
528
- } elseif ( $_GET['schedule'] == 'upcoming' ) {
529
- $where .= " AND p.post_date >= '" . date( 'Y-m-d H:i:s', current_time( 'timestamp' ) - 3600 ) . "'";
530
  }
 
 
 
 
531
  }
532
 
533
 
@@ -569,7 +591,7 @@ class rtbBookingsTable extends WP_List_Table {
569
  $args['orderby'] = $_GET['orderby'];
570
  }
571
 
572
- $args['order'] = isset( $_GET['order'] ) ? $_GET['order'] : 'ASC';
573
 
574
  if ( $this->filter_start_date !== null || $this->filter_end_date !== null ) {
575
 
@@ -587,7 +609,7 @@ class rtbBookingsTable extends WP_List_Table {
587
  $args['date_query'] = $date_query;
588
  }
589
 
590
- } elseif ( isset( $_GET['schedule'] ) ) {
591
 
592
  if ( $_GET['schedule'] == 'today' ) {
593
  $today = getdate();
@@ -596,16 +618,17 @@ class rtbBookingsTable extends WP_List_Table {
596
  $args['day'] = $today['mday'];
597
  }
598
 
599
- if ( $_GET['schedule'] == 'upcoming' ) {
600
- $args['date_query'] = array(
601
- array(
602
- 'after' => '-1 hour', // show bookings that have just passed
603
- )
604
- );
605
- if ( empty( $_GET['order'] ) ) {
606
- $args['order'] = 'ASC';
607
- }
608
  }
 
609
  }
610
 
611
  $args = apply_filters( 'rtb_bookings_table_query_args', $args );
@@ -649,5 +672,51 @@ class rtbBookingsTable extends WP_List_Table {
649
  )
650
  );
651
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
652
  }
653
  } // endif;
72
 
73
  // Set parent defaults
74
  parent::__construct( array(
75
+ 'singular' => __( 'Booking', 'restaurant-reservations' ),
76
+ 'plural' => __( 'Bookings', 'restaurant-reservations' ),
77
  'ajax' => false
78
  ) );
79
 
127
  }
128
  }
129
 
130
+ /**
131
+ * Get the current date range
132
+ *
133
+ * @since 1.3
134
+ */
135
+ public function get_current_date_range() {
136
+
137
+ $range = empty( $this->filter_start_date ) ? _x( '*', 'No date limit in a date range, eg 2014-* would mean any date from 2014 or after', 'restaurant-reservations' ) : $this->filter_start_date;
138
+ $range .= empty( $this->filter_start_date ) || empty( $this->filter_end_date ) ? '' : _x( '&mdash;', 'Separator between two dates in a date range', 'restaurant-reservations' );
139
+ $range .= empty( $this->filter_end_date ) ? _x( '*', 'No date limit in a date range, eg 2014-* would mean any date from 2014 or after', 'restaurant-reservations' ) : $this->filter_end_date;
140
+
141
+ return $range;
142
+ }
143
+
144
  /**
145
  * Strip unwanted query vars from the query string or ensure the correct
146
  * vars are passed around and those we don't want to preserve are discarded.
183
  $schedule_query_string = remove_query_arg( array( 'schedule', 'start-date', 'end-date' ), $this->query_string );
184
 
185
  $views = array(
186
+ 'upcoming' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'paged' => FALSE ), remove_query_arg( array( 'schedule' ), $schedule_query_string ) ), $schedule === '' ? ' class="current"' : '', __( 'Upcoming', 'restaurant-reservations' ) ),
187
+ 'today' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'schedule' => 'today', 'paged' => FALSE ), $schedule_query_string ), $schedule === 'today' ? ' class="current"' : '', __( 'Today', 'restaurant-reservations' ) ),
188
+ 'all' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'schedule' => 'all', 'paged' => FALSE ), $schedule_query_string ), $schedule == 'all' ? ' class="current"' : '', __( 'All', 'restaurant-reservations' ) ),
189
  );
190
 
191
  if ( $schedule == 'custom' ) {
192
+ $views['custom'] = '<span class="current">' . $this->get_current_date_range() . '</span>';
 
 
193
  }
194
 
195
  $views = apply_filters( 'rtn_bookings_table_views_schedule', $views );
201
  </ul>
202
 
203
  <div class="date-filters">
204
+ <label for="start-date" class="screen-reader-text"><?php _e( 'Start Date:', 'restaurant-reservations' ); ?></label>
205
+ <input type="text" id="start-date" name="start-date" class="datepicker" value="<?php echo esc_attr( $this->filter_start_date ); ?>" placeholder="<?php _e( 'Start Date', 'restaurant-reservations' ); ?>" />
206
+ <label for="end-date" class="screen-reader-text"><?php _e( 'End Date:', 'restaurant-reservations' ); ?></label>
207
+ <input type="text" id="end-date" name="end-date" class="datepicker" value="<?php echo esc_attr( $this->filter_end_date ); ?>" placeholder="<?php _e( 'End Date', 'restaurant-reservations' ); ?>" />
208
+ <input type="submit" class="button-secondary" value="<?php _e( 'Apply', 'restaurant-reservations' ); ?>"/>
209
  <?php if( !empty( $start_date ) || !empty( $end_date ) ) : ?>
210
+ <a href="<?php echo add_query_arg( array( 'action' => 'clear_date_filters' ) ); ?>" class="button-secondary"><?php _e( 'Clear Filter', 'restaurant-reservations' ); ?></a>
211
  <?php endif; ?>
212
  </div>
213
 
221
  // email post meta as well or this search box could be
222
  // misleading for people who expect to search across all
223
  // visible data
224
+ // $this->search_box( __( 'Search', 'restaurant-reservations' ), 'rtb-bookings' );
225
  ?>
226
 
227
  <?php
237
  /**
238
  * Retrieve the view types
239
  * @since 0.0.1
 
240
  */
241
  public function get_views() {
242
 
243
  $current = isset( $_GET['status'] ) ? $_GET['status'] : '';
244
 
245
  $views = array(
246
+ 'all' => sprintf( '<a href="%s"%s>%s</a>', remove_query_arg( array( 'status', 'paged' ), $this->query_string ), $current === 'all' || $current == '' ? ' class="current"' : '', __( 'All', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['total'] . ')</span>' ),
247
+ 'pending' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'status' => 'pending', 'paged' => FALSE ), $this->query_string ), $current === 'pending' ? ' class="current"' : '', __( 'Pending', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['pending'] . ')</span>' ),
248
+ 'confirmed' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'status' => 'confirmed', 'paged' => FALSE ), $this->query_string ), $current === 'confirmed' ? ' class="current"' : '', __( 'Confirmed', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['confirmed'] . ')</span>' ),
249
+ 'closed' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'status' => 'closed', 'paged' => FALSE ), $this->query_string ), $current === 'closed' ? ' class="current"' : '', __( 'Closed', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['closed'] . ')</span>' ),
250
+ 'trash' => sprintf( '<a href="%s"%s>%s</a>', add_query_arg( array( 'status' => 'trash', 'paged' => FALSE ), $this->query_string ), $current === 'trash' ? ' class="current"' : '', __( 'Trash', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['trash'] . ')</span>' ),
251
  );
252
 
253
  return apply_filters( 'rtb_bookings_table_views_status', $views );
257
  * Generates content for a single row of the table
258
  * @since 0.0.1
259
  */
260
+ public function single_row( $item ) {
261
  static $row_class = '';
262
  $row_class = ( $row_class == '' ? 'alternate' : '' );
263
 
275
  public function get_columns() {
276
  $columns = array(
277
  'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
278
+ 'date' => __( 'Date', 'restaurant-reservations' ),
279
+ 'party' => __( 'Party', 'restaurant-reservations' ),
280
+ 'name' => __( 'Name', 'restaurant-reservations' ),
281
+ 'email' => __( 'Email', 'restaurant-reservations' ),
282
+ 'phone' => __( 'Phone', 'restaurant-reservations' ),
283
+ 'message' => __( 'Message', 'restaurant-reservations' ),
284
+ 'status' => __( 'Status', 'restaurant-reservations' )
285
  );
286
 
287
  return apply_filters( 'rtb_bookings_table_columns', $columns );
307
  switch ( $column_name ) {
308
  case 'date' :
309
  $value = $booking->format_date( $booking->date );
310
+ $value .= '<div class="status"><span class="spinner"></span> ' . __( 'Loading', 'restaurant-reservations' ) . '</div>';
311
+
312
+ if ( $booking->post_status !== 'trash' ) {
313
+ $value .= '<div class="actions">';
314
+ $value .= '<a href="#" data-id="' . esc_attr( $booking->ID ) . '" data-action="edit">' . __( 'Edit', 'restaurant-reservations' ) . '</a>';
315
+ $value .= ' | <a href="#" class="trash" data-id="' . esc_attr( $booking->ID ) . '" data-action="trash">' . __( 'Trash', 'restaurant-reservations' ) . '</a>';
316
+ $value .= '</div>';
317
+ }
318
+
319
  break;
320
  case 'party' :
321
  $value = $booking->party;
341
  if ( !empty( $rtb_controller->cpts->booking_statuses[$booking->post_status] ) ) {
342
  $value = $rtb_controller->cpts->booking_statuses[$booking->post_status]['label'];
343
  } elseif ( $booking->post_status == 'trash' ) {
344
+ $value = _x( 'Trash', 'Status label for bookings put in the trash', 'restaurant-reservations' );
345
  } else {
346
  $value = $booking->post_status;
347
  }
373
  */
374
  public function get_bulk_actions() {
375
  $actions = array(
376
+ 'delete' => __( 'Delete', 'restaurant-reservations' ),
377
+ 'set-status-confirmed' => __( 'Set To Confirmed', 'restaurant-reservations' ),
378
+ 'set-status-pending' => __( 'Set To Pending Review', 'restaurant-reservations' ),
379
+ 'set-status-closed' => __( 'Set To Closed', 'restaurant-reservations' )
380
  );
381
 
382
  return apply_filters( 'rtb_bookings_table_bulk_actions', $actions );
491
  <div id="rtb-admin-notice-bulk-<?php esc_attr( $this->last_action ); ?>" class="updated">
492
 
493
  <?php if ( $this->last_action == 'delete' ) : ?>
494
+ <p><?php echo sprintf( _n( '%d booking deleted successfully.', '%d bookings deleted successfully.', $success, 'restaurant-reservations' ), $success ); ?></p>
495
 
496
  <?php elseif ( $this->last_action == 'set-status-confirmed' ) : ?>
497
+ <p><?php echo sprintf( _n( '%d booking confirmed.', '%d bookings confirmed.', $success, 'restaurant-reservations' ), $success ); ?></p>
498
 
499
  <?php elseif ( $this->last_action == 'set-status-pending' ) : ?>
500
+ <p><?php echo sprintf( _n( '%d booking set to pending.', '%d bookings set to pending.', $success, 'restaurant-reservations' ), $success ); ?></p>
501
 
502
  <?php elseif ( $this->last_action == 'set-status-closed' ) : ?>
503
+ <p><?php echo sprintf( _n( '%d booking closed.', '%d bookings closed.', $success, 'restaurant-reservations' ), $success ); ?></p>
504
 
505
  <?php endif; ?>
506
  </div>
512
  ?>
513
 
514
  <div id="rtb-admin-notice-bulk-<?php esc_attr( $this->last_action ); ?>" class="error">
515
+ <p><?php echo sprintf( _n( '%d booking had errors and could not be processed.', '%d bookings had errors and could not be processed.', $failure, 'restaurant-reservations' ), $failure ); ?></p>
516
  </div>
517
 
518
  <?php
540
  $end_date = new DateTime( $this->filter_end_date );
541
  $where .= " AND p.post_date <= '" . $end_date->format( 'Y-m-d H:i:s' ) . "'";
542
  }
543
+
544
  } elseif ( !empty( $_GET['schedule'] ) ) {
545
 
546
  if ( $_GET['schedule'] == 'today' ) {
547
  $where .= " AND p.post_date >= '" . date( 'Y-m-d' ) . "' AND p.post_date <= '" . date( 'Y-m-d', current_time( 'timestamp' ) + 86400 ) . "'";
 
 
 
548
  }
549
+
550
+ // Default date setting is to show upcoming bookings
551
+ } else {
552
+ $where .= " AND p.post_date >= '" . date( 'Y-m-d H:i:s', current_time( 'timestamp' ) - 3600 ) . "'";
553
  }
554
 
555
 
591
  $args['orderby'] = $_GET['orderby'];
592
  }
593
 
594
+ $args['order'] = !empty( $_GET['order'] ) ? $_GET['order'] : 'ASC';
595
 
596
  if ( $this->filter_start_date !== null || $this->filter_end_date !== null ) {
597
 
609
  $args['date_query'] = $date_query;
610
  }
611
 
612
+ } elseif ( !empty( $_GET['schedule'] ) ) {
613
 
614
  if ( $_GET['schedule'] == 'today' ) {
615
  $today = getdate();
618
  $args['day'] = $today['mday'];
619
  }
620
 
621
+ // Default date setting is to show upcoming bookings
622
+ } elseif ( empty( $_GET['schedule'] ) ) {
623
+ $args['date_query'] = array(
624
+ array(
625
+ 'after' => '-1 hour', // show bookings that have just passed
626
+ )
627
+ );
628
+ if ( empty( $_GET['order'] ) ) {
629
+ $args['order'] = 'ASC';
630
  }
631
+
632
  }
633
 
634
  $args = apply_filters( 'rtb_bookings_table_query_args', $args );
672
  )
673
  );
674
  }
675
+
676
+ /**
677
+ * Add notifications above the table to indicate which bookings are
678
+ * being shown.
679
+ * @since 1.3
680
+ */
681
+ public function display_rows_or_placeholder() {
682
+
683
+ global $rtb_controller;
684
+
685
+ $notifications = array();
686
+
687
+ $status = '';
688
+ if ( !empty( $_GET['status'] ) ) {
689
+ $status = $_GET['status'];
690
+ if ( $status == 'trash' ) {
691
+ $notifications['status'] = __( "You're viewing bookings that have been moved to the trash.", 'restaurant-reservations' );
692
+ } elseif ( !empty( $rtb_controller->cpts->booking_statuses[ $status ] ) ) {
693
+ $notifications['status'] = sprintf( _x( "You're viewing bookings that have been marked as %s.", 'Indicates which booking status is currently being filtered in the list of bookings.', 'restaurant-reservations' ), $rtb_controller->cpts->booking_statuses[ $_GET['status'] ]['label'] );
694
+ }
695
+ }
696
+
697
+ if ( !empty( $this->filter_start_date ) || !empty( $this->filter_end_date ) ) {
698
+ $notifications['date'] = sprintf( _x( 'Only bookings from %s are being shown.', 'Notification of booking date range, eg - bookings from 2014-12-02-2014-12-05', 'restaurant-reservations' ), $this->get_current_date_range() );
699
+ } elseif ( !empty( $_GET['schedule'] ) && $_GET['schedule'] == 'today' ) {
700
+ $notifications['date'] = __( "Only today's bookings are being shown.", 'restaurant-reservations' );
701
+ } elseif ( empty( $_GET['schedule'] ) ) {
702
+ $notifications['date'] = __( 'Only upcoming bookings are being shown.', 'restaurant-reservations' );
703
+ }
704
+
705
+ $notifications = apply_filters( 'rtb_admin_bookings_table_filter_notifications', $notifications );
706
+
707
+ if ( !empty( $notifications ) ) :
708
+ ?>
709
+
710
+ <tr class="notice <?php echo esc_attr( $status ); ?>">
711
+ <td colspan="<?php echo count( $this->get_columns() ); ?>">
712
+ <?php echo join( ' ', $notifications ); ?>
713
+ </td>
714
+ </tr>
715
+
716
+ <?php
717
+ endif;
718
+
719
+ parent::display_rows_or_placeholder();
720
+ }
721
  }
722
  } // endif;
includes/WP_Widget.BookingFormWidget.class.php CHANGED
@@ -22,8 +22,8 @@ class rtbBookingFormWidget extends WP_Widget {
22
 
23
  parent::__construct(
24
  'rtb_booking_form_widget',
25
- __('Booking Form', RTB_TEXTDOMAIN),
26
- array( 'description' => __( 'Display a form to accept bookings.', RTB_TEXTDOMAIN ), )
27
  );
28
 
29
  }
22
 
23
  parent::__construct(
24
  'rtb_booking_form_widget',
25
+ __('Booking Form', 'restaurant-reservations'),
26
+ array( 'description' => __( 'Display a form to accept bookings.', 'restaurant-reservations' ), )
27
  );
28
 
29
  }
includes/template-functions.php CHANGED
@@ -43,7 +43,7 @@ function rtb_print_booking_form() {
43
  // Process a booking request
44
  if ( !empty( $_POST['action'] ) && $_POST['action'] == 'booking_request' ) {
45
 
46
- if ( empty( $rtb_controller->request ) ) {
47
  require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
48
  $rtb_controller->request = new rtbBooking();
49
  }
@@ -51,94 +51,21 @@ function rtb_print_booking_form() {
51
  $rtb_controller->request->insert_booking();
52
  }
53
 
54
- // Set up a dummy request object if no request has been made. This just
55
- // simplifies the display of values in the form below
56
- if ( empty( $rtb_controller->request ) ) {
57
- $request = new stdClass();
58
- $request->request_processed = false;
59
- $request->request_inserted = false;
60
- } else {
61
- $request = $rtb_controller->request;
62
- }
63
-
64
  // Define the form's action parameter
65
  $booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
66
  if ( !empty( $booking_page ) ) {
67
  $booking_page = get_permalink( $booking_page );
68
  }
69
 
70
- // Define the form fields
71
- //
72
- // This array defines the field details and a callback function to
73
- // render each field. To customize the form output, modify the
74
- // callback functions to point to your custom function. Don't forget
75
- // to output an error message in your custom callback function. You
76
- // can use rtb_print_form_error( $slug ) to do this.
77
- $fields = array(
78
-
79
- // Reservation details fieldset
80
- 'reservation' => array(
81
- 'legend' => __( 'Book a table', RTB_TEXTDOMAIN ),
82
- 'fields' => array(
83
- 'date' => array(
84
- 'title' => __( 'Date', RTB_TEXTDOMAIN ),
85
- 'request_input' => empty( $request->request_date ) ? '' : $request->request_date,
86
- 'callback' => 'rtb_print_form_text_field',
87
- ),
88
- 'time' => array(
89
- 'title' => __( 'Time', RTB_TEXTDOMAIN ),
90
- 'request_input' => empty( $request->request_time ) ? '' : $request->request_time,
91
- 'callback' => 'rtb_print_form_text_field',
92
- ),
93
- 'party' => array(
94
- 'title' => __( 'Party', RTB_TEXTDOMAIN ),
95
- 'request_input' => empty( $request->party ) ? '' : $request->party,
96
- 'callback' => 'rtb_print_form_text_field',
97
- ),
98
- ),
99
- ),
100
-
101
- // Contact details fieldset
102
- 'contact' => array(
103
- 'legend' => __( 'Contact Details', RTB_TEXTDOMAIN ),
104
- 'fields' => array(
105
- 'name' => array(
106
- 'title' => __( 'Name', RTB_TEXTDOMAIN ),
107
- 'request_input' => empty( $request->name ) ? '' : $request->name,
108
- 'callback' => 'rtb_print_form_text_field',
109
- ),
110
- 'email' => array(
111
- 'title' => __( 'Email', RTB_TEXTDOMAIN ),
112
- 'request_input' => empty( $request->email ) ? '' : $request->email,
113
- 'callback' => 'rtb_print_form_text_field',
114
- ),
115
- 'phone' => array(
116
- 'title' => __( 'Phone', RTB_TEXTDOMAIN ),
117
- 'request_input' => empty( $request->phone ) ? '' : $request->phone,
118
- 'callback' => 'rtb_print_form_text_field',
119
- ),
120
- 'add-message' => array(
121
- 'title' => __( 'Add a Message', RTB_TEXTDOMAIN ),
122
- 'request_input' => '',
123
- 'callback' => 'rtb_print_form_message_link',
124
- ),
125
- 'message' => array(
126
- 'title' => __( 'Message', RTB_TEXTDOMAIN ),
127
- 'request_input' => empty( $request->message ) ? '' : $request->message,
128
- 'callback' => 'rtb_print_form_textarea_field',
129
- ),
130
- ),
131
- ),
132
- );
133
-
134
- $fields = apply_filters( 'rtb_booking_form_fields', $fields, $request );
135
 
136
  ob_start();
137
 
138
  ?>
139
 
140
  <div class="rtb-booking-form">
141
- <?php if ( $request->request_inserted === true ) : ?>
142
  <div class="rtb-message">
143
  <p><?php echo $rtb_controller->settings->get_setting( 'success-message' ); ?></p>
144
  </div>
@@ -148,27 +75,41 @@ function rtb_print_booking_form() {
148
 
149
  <?php do_action( 'rtb_booking_form_before_fields' ); ?>
150
 
151
- <?php foreach( $fields as $fieldset => $contents ) : ?>
152
- <fieldset class="<?php echo $fieldset; ?>">
 
 
 
153
 
154
  <?php if ( !empty( $contents['legend'] ) ) : ?>
155
- <legend>
156
  <?php echo $contents['legend']; ?>
157
  </legend>
158
  <?php endif; ?>
159
 
160
  <?php
161
  foreach( $contents['fields'] as $slug => $field ) {
162
- call_user_func( $field['callback'], $slug, $field['title'], $field['request_input'] );
 
 
 
163
  }
164
  ?>
165
  </fieldset>
166
  <?php endforeach; ?>
167
 
168
  <?php do_action( 'rtb_booking_form_after_fields' ); ?>
169
-
170
- <button type="submit"><?php _e( 'Request Booking', RTB_TEXTDOMAIN ); ?></button>
171
-
 
 
 
 
 
 
 
 
172
  </form>
173
  <?php endif; ?>
174
  </div>
@@ -190,6 +131,8 @@ function rtb_print_booking_form() {
190
  if ( !function_exists( 'rtb_enqueue_assets' ) ) {
191
  function rtb_enqueue_assets() {
192
 
 
 
193
  wp_enqueue_style( 'rtb-booking-form' );
194
 
195
  wp_enqueue_style( 'pickadate-default' );
@@ -295,19 +238,21 @@ function rtb_get_datepicker_rules() {
295
  * @since 1.3
296
  */
297
  if ( !function_exists( 'rtb_print_form_text_field' ) ) {
298
- function rtb_print_form_text_field( $slug, $title, $value ) {
299
 
300
  $slug = esc_attr( $slug );
301
  $value = esc_attr( $value );
 
 
302
 
303
  ?>
304
-
305
- <div class="<?php echo $slug; ?>">
306
  <?php echo rtb_print_form_error( $slug ); ?>
307
  <label for="rtb-<?php echo $slug; ?>">
308
- <?php _e( $title, RTB_TEXTDOMAIN ); ?>
309
  </label>
310
- <input type="text" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="<?php echo $value; ?>">
311
  </div>
312
 
313
  <?php
@@ -320,20 +265,54 @@ function rtb_print_form_text_field( $slug, $title, $value ) {
320
  * @since 1.3
321
  */
322
  if ( !function_exists( 'rtb_print_form_textarea_field' ) ) {
323
- function rtb_print_form_textarea_field( $slug, $title, $value ) {
324
 
325
  $slug = esc_attr( $slug );
 
 
 
326
 
327
  ?>
328
-
329
- <div class="<?php echo $slug; ?>">
330
  <?php echo rtb_print_form_error( $slug ); ?>
331
  <label for="rtb-<?php echo $slug; ?>">
332
- <?php _e( $title, RTB_TEXTDOMAIN ); ?>
333
  </label>
334
  <textarea name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>"><?php echo $value; ?></textarea>
335
  </div>
336
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
  <?php
338
 
339
  }
@@ -344,19 +323,20 @@ function rtb_print_form_textarea_field( $slug, $title, $value ) {
344
  * @since 1.3
345
  */
346
  if ( !function_exists( 'rtb_print_form_message_link' ) ) {
347
- function rtb_print_form_message_link( $slug, $title, $value ) {
348
 
349
  $slug = esc_attr( $slug );
350
  $value = esc_attr( $value );
 
351
 
352
  ?>
353
-
354
- <div class="<?php echo $slug; ?>">
355
  <a href="#">
356
- <?php _e( $title, RTB_TEXTDOMAIN ); ?>
357
  </a>
358
  </div>
359
-
360
  <?php
361
 
362
  }
@@ -380,3 +360,22 @@ function rtb_print_form_error( $field ) {
380
  }
381
  }
382
  } // endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  // Process a booking request
44
  if ( !empty( $_POST['action'] ) && $_POST['action'] == 'booking_request' ) {
45
 
46
+ if ( get_class( $rtb_controller->request ) === 'stdClass' ) {
47
  require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
48
  $rtb_controller->request = new rtbBooking();
49
  }
51
  $rtb_controller->request->insert_booking();
52
  }
53
 
 
 
 
 
 
 
 
 
 
 
54
  // Define the form's action parameter
55
  $booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
56
  if ( !empty( $booking_page ) ) {
57
  $booking_page = get_permalink( $booking_page );
58
  }
59
 
60
+ // Retrieve the form fields
61
+ $fields = $rtb_controller->settings->get_booking_form_fields( $rtb_controller->request );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  ob_start();
64
 
65
  ?>
66
 
67
  <div class="rtb-booking-form">
68
+ <?php if ( $rtb_controller->request->request_inserted === true ) : ?>
69
  <div class="rtb-message">
70
  <p><?php echo $rtb_controller->settings->get_setting( 'success-message' ); ?></p>
71
  </div>
75
 
76
  <?php do_action( 'rtb_booking_form_before_fields' ); ?>
77
 
78
+ <?php foreach( $fields as $fieldset => $contents ) :
79
+ $fieldset_classes = isset( $contents['callback_args']['classes'] ) ? $contents['callback_args']['classes'] : array();
80
+ $legend_classes = isset( $contents['callback_args']['legend_classes'] ) ? $contents['callback_args']['legend_classes'] : array();
81
+ ?>
82
+ <fieldset <?php echo rtb_print_element_class( $fieldset, $fieldset_classes ); ?>>
83
 
84
  <?php if ( !empty( $contents['legend'] ) ) : ?>
85
+ <legend <?php echo rtb_print_element_class( '', $legend_classes ); ?>>
86
  <?php echo $contents['legend']; ?>
87
  </legend>
88
  <?php endif; ?>
89
 
90
  <?php
91
  foreach( $contents['fields'] as $slug => $field ) {
92
+
93
+ $args = empty( $field['callback_args'] ) ? null : $field['callback_args'];
94
+
95
+ call_user_func( $field['callback'], $slug, $field['title'], $field['request_input'], $args );
96
  }
97
  ?>
98
  </fieldset>
99
  <?php endforeach; ?>
100
 
101
  <?php do_action( 'rtb_booking_form_after_fields' ); ?>
102
+
103
+ <?php
104
+ $button = sprintf(
105
+ '<button type="submit">%s</button>',
106
+ apply_filters( 'rtb_booking_form_submit_label', __( 'Request Booking', 'restaurant-reservations' ) )
107
+ );
108
+
109
+ echo apply_filters( 'rtb_booking_form_submit_button', $button );
110
+ ?>
111
+
112
+
113
  </form>
114
  <?php endif; ?>
115
  </div>
131
  if ( !function_exists( 'rtb_enqueue_assets' ) ) {
132
  function rtb_enqueue_assets() {
133
 
134
+ global $wp_scripts;
135
+
136
  wp_enqueue_style( 'rtb-booking-form' );
137
 
138
  wp_enqueue_style( 'pickadate-default' );
238
  * @since 1.3
239
  */
240
  if ( !function_exists( 'rtb_print_form_text_field' ) ) {
241
+ function rtb_print_form_text_field( $slug, $title, $value, $args = array() ) {
242
 
243
  $slug = esc_attr( $slug );
244
  $value = esc_attr( $value );
245
+ $type = empty( $args['input_type'] ) ? 'text' : esc_attr( $args['input_type'] );
246
+ $classes = isset( $args['classes'] ) ? $args['classes'] : array();
247
 
248
  ?>
249
+
250
+ <div <?php echo rtb_print_element_class( $slug, $classes ); ?>>
251
  <?php echo rtb_print_form_error( $slug ); ?>
252
  <label for="rtb-<?php echo $slug; ?>">
253
+ <?php echo $title; ?>
254
  </label>
255
+ <input type="<?php echo $type; ?>" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="<?php echo $value; ?>">
256
  </div>
257
 
258
  <?php
265
  * @since 1.3
266
  */
267
  if ( !function_exists( 'rtb_print_form_textarea_field' ) ) {
268
+ function rtb_print_form_textarea_field( $slug, $title, $value, $args = array() ) {
269
 
270
  $slug = esc_attr( $slug );
271
+ // Strip out <br> tags when placing in a textarea
272
+ $value = preg_replace('/\<br(\s*)?\/?\>/i', '', $value);
273
+ $classes = isset( $args['classes'] ) ? $args['classes'] : array();
274
 
275
  ?>
276
+
277
+ <div <?php echo rtb_print_element_class( $slug, $classes ); ?>>
278
  <?php echo rtb_print_form_error( $slug ); ?>
279
  <label for="rtb-<?php echo $slug; ?>">
280
+ <?php echo $title; ?>
281
  </label>
282
  <textarea name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>"><?php echo $value; ?></textarea>
283
  </div>
284
+
285
+ <?php
286
+
287
+ }
288
+ } // endif;
289
+
290
+ /**
291
+ * Print a select form field
292
+ * @since 1.3
293
+ */
294
+ if ( !function_exists( 'rtb_print_form_select_field' ) ) {
295
+ function rtb_print_form_select_field( $slug, $title, $value, $args ) {
296
+
297
+ $slug = esc_attr( $slug );
298
+ $value = esc_attr( $value );
299
+ $options = $args['options'];
300
+ $classes = isset( $args['classes'] ) ? $args['classes'] : array();
301
+
302
+ ?>
303
+
304
+ <div <?php echo rtb_print_element_class( $slug, $classes ); ?>>
305
+ <?php echo rtb_print_form_error( $slug ); ?>
306
+ <label for="rtb-<?php echo $slug; ?>">
307
+ <?php echo $title; ?>
308
+ </label>
309
+ <select name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>">
310
+ <?php foreach ( $options as $opt_value => $opt_label ) : ?>
311
+ <option value="<?php echo esc_attr( $opt_value ); ?>" <?php selected( $opt_value, $value ); ?>><?php echo esc_attr( $opt_label ); ?></option>
312
+ <?php endforeach; ?>
313
+ </select>
314
+ </div>
315
+
316
  <?php
317
 
318
  }
323
  * @since 1.3
324
  */
325
  if ( !function_exists( 'rtb_print_form_message_link' ) ) {
326
+ function rtb_print_form_message_link( $slug, $title, $value, $args = array() ) {
327
 
328
  $slug = esc_attr( $slug );
329
  $value = esc_attr( $value );
330
+ $classes = isset( $args['classes'] ) ? $args['classes'] : array();
331
 
332
  ?>
333
+
334
+ <div <?php echo rtb_print_element_class( $slug, $classes ); ?>>
335
  <a href="#">
336
+ <?php echo $title; ?>
337
  </a>
338
  </div>
339
+
340
  <?php
341
 
342
  }
360
  }
361
  }
362
  } // endif;
363
+
364
+ /**
365
+ * Print a class attribute based on the slug and optional classes, provided with arguments
366
+ * @since 1.3
367
+ */
368
+ if ( !function_exists( 'rtb_print_element_class' ) ) {
369
+ function rtb_print_element_class( $slug, $additional_classes = array() ) {
370
+ $classes = empty( $additional_classes ) ? array() : $additional_classes;
371
+
372
+ if ( ! empty( $slug ) ) {
373
+ array_push( $classes, $slug );
374
+ }
375
+
376
+ $class_attr = esc_attr( join( ' ', $classes ) );
377
+
378
+ return empty( $class_attr ) ? '' : sprintf( 'class="%s"', $class_attr );
379
+
380
+ }
381
+ } // endif;
languages/restaurant-reservations-de_DE.mo ADDED
Binary file
languages/restaurant-reservations-de_DE.po ADDED
@@ -0,0 +1,1441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Restaurant Reservations 1.2.3\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2015-01-02 18:32:51+00:00\n"
6
+ "PO-Revision-Date: Sun Jan 04 2015 16:03:59 GMT+0100\n"
7
+ "Last-Translator: admin <admin@example.com>\n"
8
+ "Language-Team: LANGUAGE <LL@li.org>\n"
9
+ "Language: German\n"
10
+ "Plural-Forms: nplurals=2; plural=n != 1\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Poedit-Basepath: .\n"
16
+ "X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
17
+ "__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
18
+ "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
19
+ "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
20
+ "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
21
+ "X-Generator: Loco - https://localise.biz/\n"
22
+ "X-Loco-Target-Locale: de_DE\n"
23
+ "X-Poedit-SearchPath-0: .."
24
+
25
+ #: includes/Addons.class.php:89
26
+ #: includes/WP_List_Table.BookingsTable.class.php:310
27
+ msgid "Loading"
28
+ msgstr "Lade ..."
29
+
30
+ #: includes/Addons.class.php:126
31
+ msgid "Addons for Restaurant Reservations"
32
+ msgstr "Erweiterungen zu Tischreservationen"
33
+
34
+ #: includes/Addons.class.php:148
35
+ msgid "You have been logged out. Please login again to retrieve the addons."
36
+ msgstr "Sie wurden abgemeldet. Bitte melden Sie sich an um Erweiterungen zu laden."
37
+
38
+ #: includes/Addons.class.php:164
39
+ msgid ""
40
+ "You do not have permission to access this page. Please login to an "
41
+ "administrator account if you have one."
42
+ msgstr ""
43
+ "Sie haben keine Zugriffrechte auf diese Seite. Bitte melden Sie sich mit "
44
+ "einem Adminstratorenkonto ein."
45
+
46
+ #: includes/Addons.class.php:190
47
+ msgid ""
48
+ "The addons list could not be retrieved. Please <a href=\"\">try again</a>. If "
49
+ "the problem persists over time, please report it on the <a href=\"http:"
50
+ "//wordpress.org/support/plugin/restaurant-reservations\" "
51
+ "target=\"_blank\">support forums</a>."
52
+ msgstr ""
53
+ "Die Liste der Erweiterungen konnte nicht geladen werden. Bitte <a "
54
+ "href=\"\">versuchen Sie es erneut</a>. Falls das Problem bestehen bleibt, so "
55
+ "melden Sie es bitte <a \n"
56
+ "href=\"http://wordpress.org/support/plugin/restaurant-reservations\" \n"
57
+ "target=\"_blank\">support forums</a>."
58
+
59
+ #: includes/AdminBookings.class.php:68
60
+ msgid "Restaurant Bookings"
61
+ msgstr "Tischreservation"
62
+
63
+ #: includes/AdminBookings.class.php:69 includes/CustomPostTypes.class.php:42
64
+ msgid "Add New"
65
+ msgstr "Neu hinzufügen"
66
+
67
+ #: includes/AdminBookings.class.php:114 restaurant-reservations.php:212
68
+ msgid "Add Booking"
69
+ msgstr "Tischreservation hinzufügen"
70
+
71
+ #: includes/AdminBookings.class.php:117
72
+ msgid "Cancel"
73
+ msgstr "Abbrechen"
74
+
75
+ #: includes/AdminBookings.class.php:131
76
+ msgid "Close"
77
+ msgstr "Schliessen"
78
+
79
+ #: includes/AdminBookings.class.php:191
80
+ msgid "Booking Status"
81
+ msgstr "Status der Tischreservation"
82
+
83
+ #: includes/AdminBookings.class.php:199
84
+ msgid "Send notifications"
85
+ msgstr "Benachrichtigunen versenden"
86
+
87
+ #: includes/AdminBookings.class.php:204
88
+ msgid "Learn more"
89
+ msgstr "mehr Infromatioenen"
90
+
91
+ #: includes/AdminBookings.class.php:205
92
+ msgid ""
93
+ "When adding a booking or changing a booking's status with this form, no "
94
+ "email notifications will be sent. Check this option if you want to send "
95
+ "email notifications."
96
+ msgstr ""
97
+ "Es werden keine Email Benachrichtigungen bei neuen Tischreservationen oder "
98
+ "Statusänderungen innerhalb dieses Formulars versandt. Wählen Sie diese "
99
+ "Option an, falls sie doch Email Benachrichtigungen versenden wollen."
100
+
101
+ #: includes/AdminBookings.class.php:259
102
+ #, c-format
103
+ msgid "You have been logged out. Please %slogin again%s."
104
+ msgstr "Sie wurden abgemeldet. Bitte %smelden%s Sie sich wieder an."
105
+
106
+ #: includes/AdminBookings.class.php:295
107
+ #, c-format
108
+ msgid ""
109
+ "This booking has been sent to the %sTrash%s where it can not be edited. Set "
110
+ "the booking to Pending or Confirmed to edit it."
111
+ msgstr ""
112
+ "Diese Tischreserversion wurde in den %sPapierkorb%s verschoben. Darum kann "
113
+ "sie nicht bearbeitet werden. Bitte setzten Sie den Status auf \"Pendent\" oder "
114
+ "\"Bestätigt\" um sie bearbeiten zu können."
115
+
116
+ #: includes/AdminBookings.class.php:312
117
+ msgid "The booking could not be retrieved. Please reload the page and try again."
118
+ msgstr ""
119
+ "Ihre Tischreservation konnte nicht geladen werden. Bitte laden Sie die Seite "
120
+ "neu und versuchen Sie es noch einmal."
121
+
122
+ #: includes/AdminBookings.class.php:377
123
+ msgid ""
124
+ "Unable to trash this post. Please try again. If you continue to have trouble,"
125
+ " please refresh the page."
126
+ msgstr ""
127
+ "Dieser Eintrag konnte nicht in den Papierkorb verschoben werden. Bitte "
128
+ "versuchen Sie es nocheinmal. Falls Sie dann immer noch Probleme haben, laden "
129
+ "Sie die Seite neu."
130
+
131
+ #: includes/Booking.class.php:178
132
+ msgid "Please enter the date you would like to book."
133
+ msgstr "Bitte geben Sie das Datum ein an dem Sie einen Tisch buchen wollen."
134
+
135
+ #: includes/Booking.class.php:188
136
+ msgid ""
137
+ "The date you entered is not valid. Please select from one of the dates in "
138
+ "the calendar."
139
+ msgstr ""
140
+ "Das eingegebene Datum ist nicht gültig. Bitte wählen Sie ein Datum im "
141
+ "Kalender."
142
+
143
+ #: includes/Booking.class.php:199
144
+ msgid "Please enter the time you would like to book."
145
+ msgstr "Bitte geben Sie die Zeit ein an dem Sie einen Tisch buchen wollen."
146
+
147
+ #: includes/Booking.class.php:209
148
+ msgid ""
149
+ "The time you entered is not valid. Please select from one of the times "
150
+ "provided."
151
+ msgstr ""
152
+ "Die eingegebene Zeit ist nicht gültig. Bitte wählen sie eine Zeit aus der "
153
+ "Zeitleiste."
154
+
155
+ #: includes/Booking.class.php:226
156
+ #, c-format
157
+ msgid "Sorry, bookings can not be made more than %s days in advance."
158
+ msgstr ""
159
+ "Wir bitten um Entschuldigung. Tische können nicht mehr als %s days im Voraus "
160
+ "gebucht werden."
161
+
162
+ #: includes/Booking.class.php:237
163
+ msgid "Sorry, bookings can not be made in the past."
164
+ msgstr ""
165
+ "Wir bitten um Entschuldigung. Tische können nicht in der Vergangenheit "
166
+ "gebucht werden."
167
+
168
+ #: includes/Booking.class.php:245
169
+ #, c-format
170
+ msgid "Sorry, bookings must be made more than %s days in advance."
171
+ msgstr ""
172
+ "Wir bitten um Entschuldigung. Tische müssen mehr als %s days im Voraus "
173
+ "gebucht werden."
174
+
175
+ #: includes/Booking.class.php:247
176
+ #, c-format
177
+ msgid "Sorry, bookings must be made more than %s hours in advance."
178
+ msgstr ""
179
+ "Wir bitten um Entschuldigung. Tische müssen mehr als %s hours im Voraus "
180
+ "gebucht werden."
181
+
182
+ #: includes/Booking.class.php:249
183
+ #, c-format
184
+ msgid "Sorry, bookings must be made more than %s mings in advance."
185
+ msgstr ""
186
+ "Wir bitten um Entschuldigung. Tische müssen mehr als %s Minuten im Voraus "
187
+ "gebucht werden."
188
+
189
+ #: includes/Booking.class.php:288
190
+ msgid "Sorry, no bookings are being accepted then."
191
+ msgstr ""
192
+ "Wir bitten um Entschuldigung. Zu diesem Zeitpunkt können wir keine "
193
+ "Tischreservationen annehmen."
194
+
195
+ #: includes/Booking.class.php:340
196
+ msgid "Sorry, no bookings are being accepted on that date."
197
+ msgstr ""
198
+ "Wir bitten um Entschuldigung. Zu diesem Datum können wir keine "
199
+ "Tischreservationen annehmen."
200
+
201
+ #: includes/Booking.class.php:346
202
+ msgid "Sorry, no bookings are being accepted at that time."
203
+ msgstr ""
204
+ "Wir bitten um Entschuldigung. Zu dieser Zeit können wir keine "
205
+ "Tischreservationen annehmen."
206
+
207
+ #: includes/Booking.class.php:368
208
+ msgid "Please enter a name for this booking."
209
+ msgstr "Bitte geben Sie an auf welchen Namen Sie den Tisch reservieren wollen."
210
+
211
+ #: includes/Booking.class.php:378
212
+ msgid "Please let us know how many people will be in your party."
213
+ msgstr "Bitte sagen sie uns wieviele Plätze Sie am Tisch benötigen."
214
+
215
+ #: includes/Booking.class.php:388
216
+ #, c-format
217
+ msgid "We only accept bookings for parties of up to %d people."
218
+ msgstr "Wir können leider nur Tischreservationen bis %d Personen annehmen."
219
+
220
+ #: includes/Booking.class.php:399
221
+ msgid "Please enter an email address so we can confirm your booking."
222
+ msgstr ""
223
+ "Bitte geben Sie Ihre Email Adresse ein damit wir Ihnen die Reservation "
224
+ "bestätigen können."
225
+
226
+ #: includes/Booking.class.php:414
227
+ msgid "Please complete this field to request a booking."
228
+ msgstr ""
229
+ "Bitte füllen Sie dieses Feld aus um eine Tischreserverationsanfrage "
230
+ "abzusenden."
231
+
232
+ #: includes/CustomPostTypes.class.php:38 includes/CustomPostTypes.class.php:40
233
+ #: includes/CustomPostTypes.class.php:41
234
+ #: includes/WP_List_Table.BookingsTable.class.php:76
235
+ msgid "Bookings"
236
+ msgstr "Tischreservationen"
237
+
238
+ #: includes/CustomPostTypes.class.php:39
239
+ #: includes/WP_List_Table.BookingsTable.class.php:75
240
+ msgid "Booking"
241
+ msgstr "Tischreservation"
242
+
243
+ #: includes/CustomPostTypes.class.php:43
244
+ msgid "Add New Booking"
245
+ msgstr "Neue Tischreservation hinzufügen"
246
+
247
+ #: includes/CustomPostTypes.class.php:44 restaurant-reservations.php:213
248
+ msgid "Edit Booking"
249
+ msgstr "Tischreservation bearbeiten"
250
+
251
+ #: includes/CustomPostTypes.class.php:45
252
+ msgid "New Booking"
253
+ msgstr "Neue Tischreservation"
254
+
255
+ #: includes/CustomPostTypes.class.php:46
256
+ msgid "View Booking"
257
+ msgstr "Tischreservation ansehen"
258
+
259
+ #: includes/CustomPostTypes.class.php:47
260
+ msgid "Search Bookings"
261
+ msgstr "Tischreservation suchen"
262
+
263
+ #: includes/CustomPostTypes.class.php:48
264
+ msgid "No bookings found"
265
+ msgstr "Keine Tischreservationen gefunden"
266
+
267
+ #: includes/CustomPostTypes.class.php:49
268
+ msgid "No bookings found in trash"
269
+ msgstr "Keine Tischreservationen im Papierkübel gefunden"
270
+
271
+ #: includes/CustomPostTypes.class.php:50
272
+ msgid "All Bookings"
273
+ msgstr "Alle Tischreservationen"
274
+
275
+ #: includes/CustomPostTypes.class.php:93
276
+ #, c-format
277
+ msgid "Confirmed <span class=\"count\">(%s)</span>"
278
+ msgid_plural "Confirmed <span class=\"count\">(%s)</span>"
279
+ msgstr[0] "Bestätigt für <span class=\"count\">(%s)</span> Gast"
280
+ msgstr[1] "Bestätigt für <span class=\"count\">(%s)</span> Gäste"
281
+
282
+ #: includes/CustomPostTypes.class.php:104
283
+ #, c-format
284
+ msgid "Closed <span class=\"count\">(%s)</span>"
285
+ msgid_plural "Closed <span class=\"count\">(%s)</span>"
286
+ msgstr[0] "Geschlossen für <span class=\"count\">(%s)</span>"
287
+ msgstr[1] "Geschlossen für <span class=\"count\">(%s)</span>"
288
+
289
+ #: includes/Notification.class.php:88
290
+ msgid "View pending bookings"
291
+ msgstr "Pendente Tischreservationen ansehen"
292
+
293
+ #: includes/Notification.class.php:89
294
+ msgid "Confirm this booking"
295
+ msgstr "Diese Tischreservation bestätigen"
296
+
297
+ #: includes/Notification.class.php:90
298
+ msgid "Reject this booking"
299
+ msgstr "Tischreservation zurückweisen"
300
+
301
+ #: includes/Settings.class.php:218 includes/Settings.class.php:219
302
+ msgid "Settings"
303
+ msgstr "Einstellungen"
304
+
305
+ #: includes/Settings.class.php:231
306
+ msgid "General"
307
+ msgstr "Generelle Einstellungen"
308
+
309
+ #: includes/Settings.class.php:242
310
+ msgid "Booking Page"
311
+ msgstr "Tischreservationsseite"
312
+
313
+ #: includes/Settings.class.php:243
314
+ msgid ""
315
+ "Select a page on your site to automatically display the booking form and "
316
+ "confirmation message."
317
+ msgstr ""
318
+ "Wähen Sie eine Seite zur automatischen Anzeige des Buchungsformulars und "
319
+ "einer Bestätigungsmitteilung."
320
+
321
+ #: includes/Settings.class.php:259
322
+ msgid "Max Party Size"
323
+ msgstr "Maximale Anzahl Personen pro Reservation"
324
+
325
+ #: includes/Settings.class.php:260
326
+ msgid "Set a maximum allowed party size for bookings."
327
+ msgstr "Definieren Sie die maximale Anzahl Gäste für eine Tischreservertion."
328
+
329
+ #: includes/Settings.class.php:272
330
+ msgid "Success Message"
331
+ msgstr "Erfolgsmeldung"
332
+
333
+ #: includes/Settings.class.php:273
334
+ msgid "Enter the message to display when a booking request is made."
335
+ msgstr "Geben Sie die Mitteilung für die Anzeige einer Tischreservationsanfrage"
336
+
337
+ #: includes/Settings.class.php:284
338
+ msgid "Date Format"
339
+ msgstr "Datumsformat"
340
+
341
+ #: includes/Settings.class.php:285
342
+ #, c-format
343
+ msgid ""
344
+ "Define how the date is formatted on the booking form. %sFormatting rules%s. "
345
+ "This only changes the format on the booking form. To change the date format "
346
+ "in notification messages, modify your general %sWordPress Settings%s."
347
+ msgstr ""
348
+ "Definieren Sie wie das Datum im Tischreservationsformular formatiert sein "
349
+ "soll. %sFormatierungsregeln%s. Es wird nur das Anzeigeformat im "
350
+ "Tischreservationsformular geändert. Um das Datumsformat in den "
351
+ "Benachrichtigungsmeldungen zu ändern, müssen Sie Ihre generellen %sWordPress "
352
+ "Einstellungen%s entsprechend anpassen."
353
+
354
+ #: includes/Settings.class.php:296
355
+ msgid "Time Format"
356
+ msgstr "Zeitformat"
357
+
358
+ #: includes/Settings.class.php:297
359
+ #, c-format
360
+ msgid ""
361
+ "Define how the time is formatted on the booking form. %sFormatting rules%s. "
362
+ "This only changes the format on the booking form. To change the time format "
363
+ "in notification messages, modify your general %sWordPress Settings%s."
364
+ msgstr ""
365
+ "Definieren Sie wie die Zeit im Tischreservationsformular formatiert \n"
366
+ "sein soll. %sFormatierungsregeln%s. Es wird nur das Anzeigeformat im \n"
367
+ "Tischreservationsformular geändert. Um das Zeitformat in den \n"
368
+ "Benachrichtigungsmeldungen zu ändern, müssen Sie Ihre generellen \n"
369
+ "%sWordPress Einstellungen%s entsprechend anpassen."
370
+
371
+ #: includes/Settings.class.php:310
372
+ msgid "Language"
373
+ msgstr "Sprache"
374
+
375
+ #: includes/Settings.class.php:311
376
+ msgid ""
377
+ "Select a language to use for the booking form datepicker if it is different "
378
+ "than your WordPress language setting."
379
+ msgstr ""
380
+ "Wählen Sie eine Sprache für die Datumsauswahl, falls diese unterschiedlich "
381
+ "von Ihrer WordPress Spracheinstellung ist."
382
+
383
+ #: includes/Settings.class.php:321
384
+ msgid "Booking Schedule"
385
+ msgstr "Tischreservationsplan"
386
+
387
+ #: includes/Settings.class.php:328
388
+ msgid "Add new scheduling rule"
389
+ msgstr "Neue Planungsregel hinzufügen"
390
+
391
+ #: includes/Settings.class.php:342
392
+ msgid "Delete scheduling rule"
393
+ msgstr "Planungsregel löschen"
394
+
395
+ #: includes/Settings.class.php:359
396
+ msgid "Schedule"
397
+ msgstr "Plan"
398
+
399
+ #: includes/Settings.class.php:360
400
+ msgid "Define the weekly schedule during which you accept bookings."
401
+ msgstr ""
402
+ "Definieren Sie den wöchentlichen Zeitraum in welchem Sie Tischreservationen "
403
+ "annehmen"
404
+
405
+ #: includes/Settings.class.php:385
406
+ msgid "Exceptions"
407
+ msgstr "Ausnahmen"
408
+
409
+ #: includes/Settings.class.php:386
410
+ msgid ""
411
+ "Define special opening hours for holidays, events or other needs. Leave the "
412
+ "time empty if you're closed all day."
413
+ msgstr ""
414
+ "Definieren Sie spezielle Öffnungszeiten während Festtagen, Veranstaltungen "
415
+ "oder bei anderen Situationen. Lassen Sie das Zeitfeld leer wenn Sie den "
416
+ "ganzen Tag geschlossen haben"
417
+
418
+ #: includes/Settings.class.php:401
419
+ msgid "Early Bookings"
420
+ msgstr "Vorausbuchungen"
421
+
422
+ #: includes/Settings.class.php:402
423
+ msgid "Select how early customers can make their booking."
424
+ msgstr "Wählen Sie wie lange im Voraus Gäste einen Tisch reservieren können"
425
+
426
+ #: includes/Settings.class.php:405
427
+ msgid "Any time"
428
+ msgstr "Immer"
429
+
430
+ #: includes/Settings.class.php:406
431
+ msgid "Up to 1 day in advance"
432
+ msgstr "Bis einen Tag im Voraus"
433
+
434
+ #: includes/Settings.class.php:407
435
+ msgid "Up to 1 week in advance"
436
+ msgstr "Bis eine Woche im Voraus"
437
+
438
+ #: includes/Settings.class.php:408
439
+ msgid "Up to 2 weeks in advance"
440
+ msgstr "Bis zwei Wochen im Voraus"
441
+
442
+ #: includes/Settings.class.php:409
443
+ msgid "Up to 30 days in advance"
444
+ msgstr "Bis 30 Tage im Voraus"
445
+
446
+ #: includes/Settings.class.php:410
447
+ msgid "Up to 90 days in advance"
448
+ msgstr "Bis 90 Tage im Voraus"
449
+
450
+ #: includes/Settings.class.php:421
451
+ msgid "Late Bookings"
452
+ msgstr "Kurzfristige Tischreservationen"
453
+
454
+ #: includes/Settings.class.php:422
455
+ msgid "Select how late customers can make their booking."
456
+ msgstr "Wählen Sie wie kurzfristig Gaste noch einen Tisch reservieren können."
457
+
458
+ #: includes/Settings.class.php:425
459
+ msgid "Up to the last minute"
460
+ msgstr "Bis zur letzen Minute"
461
+
462
+ #: includes/Settings.class.php:426
463
+ msgid "At least 15 minutes in advance"
464
+ msgstr "Bis 15 Minuten davor"
465
+
466
+ #: includes/Settings.class.php:427
467
+ msgid "At least 30 minutes in advance"
468
+ msgstr "Bis 30 Minuten davor"
469
+
470
+ #: includes/Settings.class.php:428
471
+ msgid "At least 45 minutes in advance"
472
+ msgstr "Bis 45 Minuten davor"
473
+
474
+ #: includes/Settings.class.php:429
475
+ msgid "At least 1 hour in advance"
476
+ msgstr "Bis 1 Stunde davor"
477
+
478
+ #: includes/Settings.class.php:430
479
+ msgid "At least 4 hours in advance"
480
+ msgstr "Bis 4 Stunden davor"
481
+
482
+ #: includes/Settings.class.php:431
483
+ msgid "At least 1 day in advance"
484
+ msgstr "Bis einen Tag davor"
485
+
486
+ #: includes/Settings.class.php:442
487
+ msgid "Date Pre-selection"
488
+ msgstr "Vorwahl des Datums"
489
+
490
+ #: includes/Settings.class.php:443
491
+ msgid ""
492
+ "When the booking form is loaded, should it automatically attempt to select a "
493
+ "valid date?"
494
+ msgstr ""
495
+ "Wenn ein Tischreservationsformulare geladen wurde, soll automatisch versucht "
496
+ "werden ein gültiges Datum zu wählen?"
497
+
498
+ #: includes/Settings.class.php:446
499
+ msgid "Select today if valid"
500
+ msgstr "Wählen Sie heute sofern dies gültig ist."
501
+
502
+ #: includes/Settings.class.php:447
503
+ msgid "Select today or next valid date"
504
+ msgstr "Wählen Sie heute oder das nächste gültige Datum aus"
505
+
506
+ #: includes/Settings.class.php:448
507
+ msgid "Leave empty"
508
+ msgstr "Leer lassen"
509
+
510
+ #: includes/Settings.class.php:459
511
+ msgid "Time Interval"
512
+ msgstr "Zeitspanne"
513
+
514
+ #: includes/Settings.class.php:460
515
+ msgid "Select the number of minutes between each available time."
516
+ msgstr "Wählen sie die Anzahl Minuten zwischen jeder verfügbaren Zeit."
517
+
518
+ #: includes/Settings.class.php:463
519
+ msgid "Every 30 minutes"
520
+ msgstr "Alle 30 Minuten"
521
+
522
+ #: includes/Settings.class.php:464
523
+ msgid "Every 15 minutes"
524
+ msgstr "Alle 15 Minuten"
525
+
526
+ #: includes/Settings.class.php:465
527
+ msgid "Every 10 minutes"
528
+ msgstr "Alle 10 Minuten"
529
+
530
+ #: includes/Settings.class.php:466
531
+ msgid "Every 5 minutes"
532
+ msgstr "Alle 5 Minuten"
533
+
534
+ #: includes/Settings.class.php:475
535
+ msgid "Notifications"
536
+ msgstr "Benachrichtigung"
537
+
538
+ #: includes/Settings.class.php:486
539
+ msgid "Reply-To Name"
540
+ msgstr "Name für die Rückantwort"
541
+
542
+ #: includes/Settings.class.php:487
543
+ msgid ""
544
+ "The name which should appear in the Reply-To field of a user notification "
545
+ "email"
546
+ msgstr ""
547
+ "Der Name die im Rückantwortfeld einer Benachrichtigungs-Email an einen Gast "
548
+ "erscheinen soll."
549
+
550
+ #: includes/Settings.class.php:498
551
+ msgid "Reply-To Email Address"
552
+ msgstr "Email Adresse für die Rückantwort"
553
+
554
+ #: includes/Settings.class.php:499
555
+ msgid ""
556
+ "The email address which should appear in the Reply-To field of a user "
557
+ "notification email."
558
+ msgstr ""
559
+ "Email Adresse die im Rückantwortfeld einer Benachrichtigungs-Email an einen "
560
+ "Gast erscheinen soll."
561
+
562
+ #: includes/Settings.class.php:510
563
+ msgid "Admin Notification"
564
+ msgstr "Administrator Benachrichtigung"
565
+
566
+ #: includes/Settings.class.php:511
567
+ msgid ""
568
+ "Send an email notification to an administrator when a new booking is "
569
+ "requested."
570
+ msgstr ""
571
+ "Sende eine Email Benachrichtigung an den Administrator wenn eine neue "
572
+ "Tischreservation angefragt worden ist."
573
+
574
+ #: includes/Settings.class.php:521
575
+ msgid "Admin Email Address"
576
+ msgstr "Email Adresse des Administrators"
577
+
578
+ #: includes/Settings.class.php:522
579
+ msgid "The email address where admin notifications should be sent."
580
+ msgstr ""
581
+ "Email Adresse an die Administratoren-Benachrichtigungen gesendet werden "
582
+ "sollen."
583
+
584
+ #: includes/Settings.class.php:531
585
+ msgid "Email Templates"
586
+ msgstr "Email Vorlagen"
587
+
588
+ #: includes/Settings.class.php:543
589
+ msgid "Template Tags"
590
+ msgstr "Vorlagen Tags"
591
+
592
+ #: includes/Settings.class.php:545
593
+ msgid ""
594
+ "Use the following tags to automatically add booking information to the "
595
+ "emails. Tags labeled with an asterisk (*) can be used in the email subject "
596
+ "as well."
597
+ msgstr ""
598
+ "Verwenden Sie die nachfolgenden Tags um Reservationsinformationen den Emails "
599
+ "hinzuzufügen. Tages die mit einem Stern (*) bezeichnet sind können auch in "
600
+ "der Betreffzeile verwendet werden."
601
+
602
+ #: includes/Settings.class.php:556
603
+ msgid "Admin Notification Subject"
604
+ msgstr "Betreffzeile für Adminstratorenbenachrichtigungen"
605
+
606
+ #: includes/Settings.class.php:557
607
+ msgid "The email subject for admin notifications."
608
+ msgstr "Email Betreffzeile für Adminstratorenbenachrichtigungen"
609
+
610
+ #: includes/Settings.class.php:568
611
+ msgid "Admin Notification Email"
612
+ msgstr "Email für Adminstratorenbenachrichtigungen"
613
+
614
+ #: includes/Settings.class.php:569
615
+ msgid ""
616
+ "Enter the email an admin should receive when an initial booking request is "
617
+ "made."
618
+ msgstr ""
619
+ "Geben Sie die Email ein, die ein Adminstrator bei einer ersten "
620
+ "Tischreservationsanfrage erhalten soll."
621
+
622
+ #: includes/Settings.class.php:580
623
+ msgid "New Request Email Subject"
624
+ msgstr "Betreffzeile für eine neue Tischreservationsanfrage"
625
+
626
+ #: includes/Settings.class.php:581
627
+ msgid ""
628
+ "The email subject a user should receive when they make an initial booking "
629
+ "request."
630
+ msgstr "Die Email-Betreffzeile für eine neue Tischreservationsanfrage"
631
+
632
+ #: includes/Settings.class.php:592
633
+ msgid "New Request Email"
634
+ msgstr "Email einer neuer Tischreservationsanfrage"
635
+
636
+ #: includes/Settings.class.php:593
637
+ msgid ""
638
+ "Enter the email a user should receive when they make an initial booking "
639
+ "request."
640
+ msgstr ""
641
+ "Geben Sie die Email die ein Gast erhalten soll, wenn er eine erste Anfrage "
642
+ "für eine Tischreservation erhalten soll."
643
+
644
+ #: includes/Settings.class.php:604
645
+ msgid "Confirmed Email Subject"
646
+ msgstr "Betreffzeile für ein Bestätigungsemail"
647
+
648
+ #: includes/Settings.class.php:605
649
+ msgid ""
650
+ "The email subject a user should receive when their booking has been "
651
+ "confirmed."
652
+ msgstr ""
653
+ "Betreffzeile einer Email die ein Gast erhalten soll wenn seine "
654
+ "Tischreservation bestätigt worden ist."
655
+
656
+ #: includes/Settings.class.php:616
657
+ msgid "Confirmed Email"
658
+ msgstr "Bestätigungs-Email"
659
+
660
+ #: includes/Settings.class.php:617
661
+ msgid "Enter the email a user should receive when their booking has been confirmed."
662
+ msgstr ""
663
+ "Geben Sie die Email ein die Gast erhalten soll, wenn seine Tischreservation "
664
+ "bestätigt worden ist."
665
+
666
+ #: includes/Settings.class.php:628
667
+ msgid "Rejected Email Subject"
668
+ msgstr "Betreffzeile für ein Ablehnungs-Email"
669
+
670
+ #: includes/Settings.class.php:629
671
+ msgid "The email subject a user should receive when their booking has been rejected."
672
+ msgstr ""
673
+ "Betreffzeile für einer Email die ein Gast erhalten soll falls seine "
674
+ "Tischreservationsanfrage abgelehnt werden musste."
675
+
676
+ #: includes/Settings.class.php:640
677
+ msgid "Rejected Email"
678
+ msgstr "Ablehunungs-Email"
679
+
680
+ #: includes/Settings.class.php:641
681
+ msgid "Enter the email a user should receive when their booking has been rejected."
682
+ msgstr ""
683
+ "Geben Sie die Email ein die ein Gast erhalten soll, falls seine "
684
+ "Tischreservationsanfrage abgelehnt werden musste."
685
+
686
+ #: includes/Settings.class.php:659
687
+ msgid "Any size"
688
+ msgstr "Beliebige Anzahl"
689
+
690
+ #: includes/Settings.class.php:714
691
+ msgid "Book a table"
692
+ msgstr "Bitte geben Sie das gewünschte Datum ein:"
693
+
694
+ #: includes/Settings.class.php:717
695
+ #: includes/WP_List_Table.BookingsTable.class.php:278
696
+ msgid "Date"
697
+ msgstr "Datum"
698
+
699
+ #: includes/Settings.class.php:723
700
+ msgid "Time"
701
+ msgstr "Zeit"
702
+
703
+ #: includes/Settings.class.php:729
704
+ #: includes/WP_List_Table.BookingsTable.class.php:279
705
+ msgid "Party"
706
+ msgstr "Personen"
707
+
708
+ #: includes/Settings.class.php:742
709
+ msgid "Contact Details"
710
+ msgstr "Kontaktdaten"
711
+
712
+ #: includes/Settings.class.php:745
713
+ #: includes/WP_List_Table.BookingsTable.class.php:280
714
+ msgid "Name"
715
+ msgstr "Name"
716
+
717
+ #: includes/Settings.class.php:751
718
+ #: includes/WP_List_Table.BookingsTable.class.php:281
719
+ msgid "Email"
720
+ msgstr "Email"
721
+
722
+ #: includes/Settings.class.php:760
723
+ #: includes/WP_List_Table.BookingsTable.class.php:282
724
+ msgid "Phone"
725
+ msgstr "Telefonnummer"
726
+
727
+ #: includes/Settings.class.php:768
728
+ msgid "Add a Message"
729
+ msgstr ">Hier< eine Nachricht hinzufügen"
730
+
731
+ #: includes/Settings.class.php:773
732
+ #: includes/WP_List_Table.BookingsTable.class.php:283
733
+ msgid "Message"
734
+ msgstr "Meldung"
735
+
736
+ #: includes/Settings.class.php:818
737
+ msgid "Email of the user who made the booking"
738
+ msgstr "* Email an den Gast der die Reservation gemacht hat"
739
+
740
+ #: includes/Settings.class.php:819
741
+ msgid "* Name of the user who made the booking"
742
+ msgstr "* Name auf den der Tisch reserviert ist"
743
+
744
+ #: includes/Settings.class.php:820
745
+ msgid "* Number of people booked"
746
+ msgstr "* Anzahl der Gäste"
747
+
748
+ #: includes/Settings.class.php:821
749
+ msgid "* Date and time of the booking"
750
+ msgstr "* Datum und Zeit der Tischreservation"
751
+
752
+ #: includes/Settings.class.php:822
753
+ msgid "Phone number if supplied with the request"
754
+ msgstr "Telefonnummer der Anfrage, falls angegeben"
755
+
756
+ #: includes/Settings.class.php:823
757
+ msgid "Message added to the request"
758
+ msgstr "Gästemitteilung die der Anfrage hinzugefügt wurden"
759
+
760
+ #: includes/Settings.class.php:824
761
+ msgid "A link to the admin panel showing pending bookings"
762
+ msgstr "Verweis zum Admin Panel das pendente Tischreservationen anzeigt "
763
+
764
+ #: includes/Settings.class.php:825
765
+ msgid "A link to confirm this booking. Only include this in admin notifications"
766
+ msgstr ""
767
+ "Link um diese Tischreservation zu bestätigen. Nur bei Benachrichtigungen für "
768
+ "Administratoren einfügen"
769
+
770
+ #: includes/Settings.class.php:826
771
+ msgid "A link to reject this booking. Only include this in admin notifications"
772
+ msgstr ""
773
+ "Link um diese Tischreservation abzulehnen. Nur bei Benachrichtigungen für "
774
+ "Administratoren einfügen"
775
+
776
+ #: includes/Settings.class.php:827
777
+ msgid "The name of this website"
778
+ msgstr "Der Name dieser Webseite"
779
+
780
+ #: includes/Settings.class.php:828
781
+ msgid "A link to this website"
782
+ msgstr "Ein Link zu dieser Webseite"
783
+
784
+ #: includes/Settings.class.php:829
785
+ msgid "Current date and time"
786
+ msgstr "Aktuelle Zeit und Datum"
787
+
788
+ #: includes/WP_List_Table.BookingsTable.class.php:186
789
+ msgid "Upcoming"
790
+ msgstr "Bald"
791
+
792
+ #: includes/WP_List_Table.BookingsTable.class.php:187
793
+ msgid "Today"
794
+ msgstr "Heute"
795
+
796
+ #: includes/WP_List_Table.BookingsTable.class.php:188
797
+ #: includes/WP_List_Table.BookingsTable.class.php:246
798
+ msgid "All"
799
+ msgstr "Alle"
800
+
801
+ #: includes/WP_List_Table.BookingsTable.class.php:204
802
+ msgid "Start Date:"
803
+ msgstr "Startdatum:"
804
+
805
+ #: includes/WP_List_Table.BookingsTable.class.php:205
806
+ msgid "Start Date"
807
+ msgstr "Startdatum"
808
+
809
+ #: includes/WP_List_Table.BookingsTable.class.php:206
810
+ msgid "End Date:"
811
+ msgstr "Enddatum:"
812
+
813
+ #: includes/WP_List_Table.BookingsTable.class.php:207
814
+ msgid "End Date"
815
+ msgstr "Enddatum"
816
+
817
+ #: includes/WP_List_Table.BookingsTable.class.php:208
818
+ msgid "Apply"
819
+ msgstr "Anwenden"
820
+
821
+ #: includes/WP_List_Table.BookingsTable.class.php:210
822
+ msgid "Clear Filter"
823
+ msgstr "Filter löschen"
824
+
825
+ #: includes/WP_List_Table.BookingsTable.class.php:247
826
+ msgid "Pending"
827
+ msgstr "Pendent"
828
+
829
+ #: includes/WP_List_Table.BookingsTable.class.php:248
830
+ msgid "Confirmed"
831
+ msgstr "Bestätigt"
832
+
833
+ #: includes/WP_List_Table.BookingsTable.class.php:249
834
+ msgid "Closed"
835
+ msgstr "Geschlossen"
836
+
837
+ #: includes/WP_List_Table.BookingsTable.class.php:250
838
+ #: includes/WP_List_Table.BookingsTable.class.php:315
839
+ msgid "Trash"
840
+ msgstr "Papierkorb"
841
+
842
+ #: includes/WP_List_Table.BookingsTable.class.php:284
843
+ msgid "Status"
844
+ msgstr "Status"
845
+
846
+ #: includes/WP_List_Table.BookingsTable.class.php:314
847
+ msgid "Edit"
848
+ msgstr "Bearbeiten"
849
+
850
+ #: includes/WP_List_Table.BookingsTable.class.php:376
851
+ msgid "Delete"
852
+ msgstr "Löschen"
853
+
854
+ #: includes/WP_List_Table.BookingsTable.class.php:377
855
+ msgid "Set To Confirmed"
856
+ msgstr "Auf \"Bestätigt\" gestellt"
857
+
858
+ #: includes/WP_List_Table.BookingsTable.class.php:378
859
+ msgid "Set To Pending Review"
860
+ msgstr "Auf \"Pendent\" gestellt"
861
+
862
+ #: includes/WP_List_Table.BookingsTable.class.php:379
863
+ msgid "Set To Closed"
864
+ msgstr "Auf \"Geschlossen\" gestellt"
865
+
866
+ #: includes/WP_List_Table.BookingsTable.class.php:494
867
+ #, c-format
868
+ msgid "%d booking deleted successfully."
869
+ msgid_plural "%d bookings deleted successfully."
870
+ msgstr[0] "%d Tischreservation erfolgreich gelöscht "
871
+ msgstr[1] "%d Tischreservationen erfolgreich gelöscht "
872
+
873
+ #: includes/WP_List_Table.BookingsTable.class.php:497
874
+ #, c-format
875
+ msgid "%d booking confirmed."
876
+ msgid_plural "%d bookings confirmed."
877
+ msgstr[0] "%d Tischreservation bestätigt "
878
+ msgstr[1] "%d Tischreservationen bestätigt "
879
+
880
+ #: includes/WP_List_Table.BookingsTable.class.php:500
881
+ #, c-format
882
+ msgid "%d booking set to pending."
883
+ msgid_plural "%d bookings set to pending."
884
+ msgstr[0] "%d Tischreservation pendent gestellt"
885
+ msgstr[1] "%d Tischreservationen pendent gestellt"
886
+
887
+ #: includes/WP_List_Table.BookingsTable.class.php:503
888
+ #, c-format
889
+ msgid "%d booking closed."
890
+ msgid_plural "%d bookings closed."
891
+ msgstr[0] "%d Tischreservation geschlossen"
892
+ msgstr[1] "%d Tischreservationen geschlossen"
893
+
894
+ #: includes/WP_List_Table.BookingsTable.class.php:515
895
+ #, c-format
896
+ msgid "%d booking had errors and could not be processed."
897
+ msgid_plural "%d bookings had errors and could not be processed."
898
+ msgstr[0] "%d Tischreservation hatte Fehler und konnte nicht verarbeitet werden."
899
+ msgstr[1] "%d Tischreservationen hatte Fehler und konnte nicht verarbeitet werden."
900
+
901
+ #: includes/WP_List_Table.BookingsTable.class.php:689
902
+ msgid "You're viewing bookings that have been moved to the trash."
903
+ msgstr "Sie sehen Tischreservationen die in den Papierkorb verschoben worden sind."
904
+
905
+ #: includes/WP_List_Table.BookingsTable.class.php:698
906
+ msgid "Only today's bookings are being shown."
907
+ msgstr "Es werden nur Tischreservationen von heute angezeigt."
908
+
909
+ #: includes/WP_List_Table.BookingsTable.class.php:700
910
+ msgid "Only upcoming bookings are being shown."
911
+ msgstr "Es werden nur zukünfitige Tischreservationen angezeigt."
912
+
913
+ #: includes/WP_Widget.BookingFormWidget.class.php:25
914
+ msgid "Booking Form"
915
+ msgstr "Tischreservationsformular"
916
+
917
+ #: includes/WP_Widget.BookingFormWidget.class.php:26
918
+ msgid "Display a form to accept bookings."
919
+ msgstr "Anzeige eines Formulars um Tischreservationen anzunehmen."
920
+
921
+ #: includes/WP_Widget.BookingFormWidget.class.php:64
922
+ msgid "Title"
923
+ msgstr "Titel"
924
+
925
+ #: includes/template-functions.php:100
926
+ msgid "Request Booking"
927
+ msgstr "Anfrage absenden"
928
+
929
+ #: restaurant-reservations.php:148
930
+ msgid "Booking Manager"
931
+ msgstr "Tischreservationsverwaltung"
932
+
933
+ #: restaurant-reservations.php:214
934
+ msgid ""
935
+ "An unspecified error occurred. Please try again. If the problem persists, "
936
+ "try logging out and logging back in."
937
+ msgstr ""
938
+ "Ein nicht spezifizierter Fehler ist aufgetreten. Bitte versuchen Sie es "
939
+ "erneut. Falls das Problem dann immer noch besteht, versuchen Sie es mit Aus- "
940
+ "und Einloggen."
941
+
942
+ #: restaurant-reservations.php:276
943
+ msgid "View the help documentation for Restaurant Reservations"
944
+ msgstr "Hilfeanleitung für Tischreservationen"
945
+
946
+ #: restaurant-reservations.php:276
947
+ msgid "Help"
948
+ msgstr "Hilfe"
949
+
950
+ #. Plugin Name of the plugin/theme
951
+ msgid "Restaurant Reservations"
952
+ msgstr "Tischreservationen"
953
+
954
+ #. #-#-#-#-# restaurant-reservations.pot (Restaurant Reservations 1.2.3) #-#-#-#-#
955
+ #. Plugin URI of the plugin/theme
956
+ #. #-#-#-#-# restaurant-reservations.pot (Restaurant Reservations 1.2.3) #-#-#-#-#
957
+ #. Author URI of the plugin/theme
958
+ msgid "http://themeofthecrop.com"
959
+ msgstr "http://themeofthecrop.com"
960
+
961
+ #. Description of the plugin/theme
962
+ msgid "Accept restaurant reservations and bookings online."
963
+ msgstr "Nehmen Sie online Tischreservationen für Ihr Restaurant an."
964
+
965
+ #. Author of the plugin/theme
966
+ msgid "Theme of the Crop"
967
+ msgstr "Ein Theme von The Crop"
968
+
969
+ #: includes/Addons.class.php:90
970
+ msgctxt "Error message when retrieving list of addons"
971
+ msgid "An unknown error occured."
972
+ msgstr "Ein unbekannter Fehler beim Lader der Liste der Erweiterungen ist aufgetreten"
973
+
974
+ #: includes/Addons.class.php:91
975
+ msgctxt "Label for an addon that is already installed and activated."
976
+ msgid "Already Installed"
977
+ msgstr "Die Erweiterung ist schon installiert"
978
+
979
+ #: includes/Addons.class.php:92
980
+ msgctxt "Label for an addon that is not yet released."
981
+ msgid "Coming Soon"
982
+ msgstr "Diese Erweiterung wird bald freigegeben"
983
+
984
+ #: includes/Addons.class.php:93
985
+ msgctxt "Label for an addon that is free."
986
+ msgid "Free"
987
+ msgstr "Diese Erweiterung ist kostenfrei"
988
+
989
+ #: includes/Addons.class.php:94
990
+ msgctxt "Label for an addon that is released."
991
+ msgid "Get It"
992
+ msgstr "Diese Erweiterung ist verfügbar"
993
+
994
+ #: includes/Addons.class.php:108
995
+ msgctxt "Title of addons page"
996
+ msgid "Addons"
997
+ msgstr "Erweiterungen"
998
+
999
+ #: includes/Addons.class.php:109
1000
+ msgctxt "Title of addons page in the admin menu"
1001
+ msgid "Addons"
1002
+ msgstr "Erweiterungen"
1003
+
1004
+ #: includes/AdminBookings.class.php:44
1005
+ msgctxt "Title of admin page that lists bookings"
1006
+ msgid "Bookings"
1007
+ msgstr "Tischreservationen"
1008
+
1009
+ #: includes/AdminBookings.class.php:45
1010
+ msgctxt "Title of bookings admin menu item"
1011
+ msgid "Bookings"
1012
+ msgstr "Tischreservation"
1013
+
1014
+ #: includes/CustomPostTypes.class.php:80
1015
+ msgctxt "Booking status when it is pending review"
1016
+ msgid "Pending"
1017
+ msgstr "Pendent"
1018
+
1019
+ #: includes/CustomPostTypes.class.php:86
1020
+ msgctxt "Booking status for a confirmed booking"
1021
+ msgid "Confirmed"
1022
+ msgstr "Bestätigt"
1023
+
1024
+ #: includes/CustomPostTypes.class.php:97
1025
+ msgctxt "Booking status for a closed booking"
1026
+ msgid "Closed"
1027
+ msgstr "Geschlossen"
1028
+
1029
+ #: includes/Settings.class.php:83
1030
+ msgctxt "restaurant-reservations"
1031
+ msgid ""
1032
+ "Thanks, your booking request is waiting to be confirmed. Updates will be "
1033
+ "sent to the email address you provided."
1034
+ msgstr ""
1035
+ "Vielen Dank. Ihre Tischreservationsanfrage ist bei uns in Bearbeitung. Wir "
1036
+ "werden Ihnen Aktualisierungen an die Email Adresse senden die Sie uns "
1037
+ "hinterlassen haben."
1038
+
1039
+ #: includes/Settings.class.php:84
1040
+ msgctxt ""
1041
+ "Default date format for display. Must match formatting rules at http://amsul."
1042
+ "ca/pickadate.js/date.htm#formatting-rules"
1043
+ msgid "mmmm d, yyyy"
1044
+ msgstr "dd.mm.yy"
1045
+
1046
+ #: includes/Settings.class.php:85
1047
+ msgctxt ""
1048
+ "Default time format for display. Must match formatting rules at http://amsul."
1049
+ "ca/pickadate.js/time.htm#formats"
1050
+ msgid "h:i A"
1051
+ msgstr "HH:i"
1052
+
1053
+ #: includes/Settings.class.php:86
1054
+ msgctxt "Default interval in minutes when selecting a time."
1055
+ msgid "30"
1056
+ msgstr "30"
1057
+
1058
+ #: includes/Settings.class.php:96
1059
+ msgctxt "Default email subject for admin notifications of new bookings"
1060
+ msgid "New Booking Request"
1061
+ msgstr "Neue Tischreservationsanfrage"
1062
+
1063
+ #: includes/Settings.class.php:97
1064
+ msgctxt ""
1065
+ "Default email sent to the admin when a new booking request is made. The tags "
1066
+ "in {brackets} will be replaced by the appropriate content and should be left "
1067
+ "in place. HTML is allowed, but be aware that many email clients do not "
1068
+ "handle HTML very well."
1069
+ msgid ""
1070
+ "A new booking request has been made at {site_name}:\n"
1071
+ "\n"
1072
+ "{user_name}\n"
1073
+ "{party} people\n"
1074
+ "{date}\n"
1075
+ "\n"
1076
+ "{bookings_link}\n"
1077
+ "{confirm_link}\n"
1078
+ "{close_link}\n"
1079
+ "\n"
1080
+ "&nbsp;\n"
1081
+ "\n"
1082
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
1083
+ msgstr ""
1084
+ "Auf {site_name} wurde eine neue Anfrage für eine Tischreservation gemacht:\n"
1085
+ "\n"
1086
+ "Auf den Namen: {user_name}\n"
1087
+ "Für: {party} Personen\n"
1088
+ "Am. {date}\n"
1089
+ "\n"
1090
+ "{bookings_link}\n"
1091
+ "{confirm_link}\n"
1092
+ "{close_link}\n"
1093
+ "\n"
1094
+ "&nbsp;\n"
1095
+ "\n"
1096
+ "<em>Diese Mitteilung wurde von {site_link} am {current_time} versandt.</em>"
1097
+
1098
+ #: includes/Settings.class.php:115
1099
+ #, c-format
1100
+ msgctxt ""
1101
+ "Default email subject sent to user when they request a booking. %s will be "
1102
+ "replaced by the website name"
1103
+ msgid "Your booking at %s is pending"
1104
+ msgstr "Ihre Tischreservation beim %s ist pendent"
1105
+
1106
+ #: includes/Settings.class.php:116
1107
+ msgctxt ""
1108
+ "Default email sent to users when they make a new booking request. The tags "
1109
+ "in {brackets} will be replaced by the appropriate content and should be left "
1110
+ "in place. HTML is allowed, but be aware that many email clients do not "
1111
+ "handle HTML very well."
1112
+ msgid ""
1113
+ "Thanks {user_name},\n"
1114
+ "\n"
1115
+ "Your booking request is <strong>waiting to be confirmed</strong>.\n"
1116
+ "\n"
1117
+ "Give us a few moments to make sure that we've got space for you. You will "
1118
+ "receive another email from us soon. If this request was made outside of our "
1119
+ "normal working hours, we may not be able to confirm it until we're open "
1120
+ "again.\n"
1121
+ "\n"
1122
+ "<strong>Your request details:</strong>\n"
1123
+ "{user_name}\n"
1124
+ "{party} people\n"
1125
+ "{date}\n"
1126
+ "\n"
1127
+ "&nbsp;\n"
1128
+ "\n"
1129
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
1130
+ msgstr ""
1131
+ "Herzlichen Dank\n"
1132
+ "\n"
1133
+ "Ihre Anfrage für einen Tisch ist <strong>bei uns in Bearbeitung</strong>.\n"
1134
+ "\n"
1135
+ "Bitte geben Sie uns einige Momente damit wir abklären können ob wir noch "
1136
+ "Platz haben.\n"
1137
+ "\n"
1138
+ "Sie erhalten bald eine Email von uns. Falls Sie Ihre Anfrage ausserhalb "
1139
+ "unserer Öfnungszeiten abgeschickt haben, werden wir sie erst bearbeiten "
1140
+ "können wenn wir wieder offen haben.\n"
1141
+ "\n"
1142
+ "\n"
1143
+ "\n"
1144
+ "<strong>Ihre Tischreservation:</strong>\n"
1145
+ "Reserviert auf den Namen: {user_name}\n"
1146
+ "Für {party} Personen\n"
1147
+ "am {date}\n"
1148
+ "\n"
1149
+ "&nbsp;\n"
1150
+ "\n"
1151
+ "<em>Diese Mitteilungen haben sie vom {site_link} um \n"
1152
+ "{current_time} erhalten.</em>"
1153
+
1154
+ #: includes/Settings.class.php:136
1155
+ msgctxt ""
1156
+ "Default email sent to users when they make a new booking request. The tags "
1157
+ "in {brackets} will be replaced by the appropriate content and should be left "
1158
+ "in place. HTML is allowed, but be aware that many email clients do not "
1159
+ "handle HTML very well."
1160
+ msgid ""
1161
+ "Hi {user_name},\n"
1162
+ "\n"
1163
+ "Your booking request has been <strong>confirmed</strong>. We look forward to "
1164
+ "seeing you soon.\n"
1165
+ "\n"
1166
+ "<strong>Your booking:</strong>\n"
1167
+ "{user_name}\n"
1168
+ "{party} people\n"
1169
+ "{date}\n"
1170
+ "\n"
1171
+ "&nbsp;\n"
1172
+ "\n"
1173
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
1174
+ msgstr ""
1175
+ "Guten Tag!\n"
1176
+ "\n"
1177
+ "Es freut uns Ihnen mitteilen zu können, dass wir Ihre Tischreservation "
1178
+ "<strong>bestätigen</strong> können. Wir freuen uns auf Ihren baldigen Besuch."
1179
+ "\n"
1180
+ "\n"
1181
+ "\n"
1182
+ " <strong>Ihre Tischreservationsdaten:</strong>\n"
1183
+ "Reservation auf den Namen: {user_name}\n"
1184
+ "für {party} Personen\n"
1185
+ "am {date}\n"
1186
+ "\n"
1187
+ "&nbsp;\n"
1188
+ "\n"
1189
+ "<em>Diese Mitteilung haben Sie vom {site_link} um {current_time} erhalten."
1190
+ "</em>"
1191
+
1192
+ #: includes/Settings.class.php:154
1193
+ msgctxt ""
1194
+ "Default email sent to users when they make a new booking request. The tags "
1195
+ "in {brackets} will be replaced by the appropriate content and should be left "
1196
+ "in place. HTML is allowed, but be aware that many email clients do not "
1197
+ "handle HTML very well."
1198
+ msgid ""
1199
+ "Hi {user_name},\n"
1200
+ "\n"
1201
+ "Sorry, we could not accomodate your booking request. We're full or not open "
1202
+ "at the time you requested:\n"
1203
+ "\n"
1204
+ "{user_name}\n"
1205
+ "{party} people\n"
1206
+ "{date}\n"
1207
+ "\n"
1208
+ "&nbsp;\n"
1209
+ "\n"
1210
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
1211
+ msgstr ""
1212
+ "Guten Tag\n"
1213
+ "\n"
1214
+ "Leider konnten wir Ihrer Anfrage für einen Tisch zum gewünschten Zeitpunkt "
1215
+ "nicht entsprechen, da wir entweder schon ausgebucht sind oder nicht offen "
1216
+ "haben.\n"
1217
+ "\n"
1218
+ "\n"
1219
+ "Ihre Reservationsdaten:\n"
1220
+ "\n"
1221
+ "\n"
1222
+ "Tischreservation auf den Namen: {user_name}\n"
1223
+ "für {party} Personen\n"
1224
+ "am {date}\n"
1225
+ "\n"
1226
+ "&nbsp;\n"
1227
+ "\n"
1228
+ "<em>Diese Mitteilung haben Sie vom {site_link} um {current_time} erhalten."
1229
+ "</em>"
1230
+
1231
+ #: includes/Settings.class.php:135
1232
+ #, c-format
1233
+ msgctxt ""
1234
+ "Default email subject sent to user when their booking is confirmed. %s will "
1235
+ "be replaced by the website name"
1236
+ msgid "Your booking at %s is confirmed"
1237
+ msgstr "Ihre Tischreservation im %s ist bestätigt."
1238
+
1239
+ #: includes/Settings.class.php:153
1240
+ #, c-format
1241
+ msgctxt ""
1242
+ "Default email subject sent to user when their booking is rejected. %s will "
1243
+ "be replaced by the website name"
1244
+ msgid "Your booking at %s was not accepted"
1245
+ msgstr "Wir konnten leider Ihrer Tischreservation im %s nicht annehmen"
1246
+
1247
+ #: includes/Settings.class.php:329
1248
+ msgctxt "Format of a scheduling rule"
1249
+ msgid "Weekly"
1250
+ msgstr "Wöchentlich"
1251
+
1252
+ #: includes/Settings.class.php:330
1253
+ msgctxt "Format of a scheduling rule"
1254
+ msgid "Monthly"
1255
+ msgstr "Monatlich"
1256
+
1257
+ #: includes/Settings.class.php:331
1258
+ msgctxt "Format of a scheduling rule"
1259
+ msgid "Date"
1260
+ msgstr "Täglich"
1261
+
1262
+ #: includes/Settings.class.php:332
1263
+ msgctxt "Label for selecting days of the week in a scheduling rule"
1264
+ msgid "Days of the week"
1265
+ msgstr "Tage einer Woche"
1266
+
1267
+ #: includes/Settings.class.php:333
1268
+ msgctxt "Label for selecting weeks of the month in a scheduling rule"
1269
+ msgid "Weeks of the month"
1270
+ msgstr "Wochen eines Monats"
1271
+
1272
+ #: includes/Settings.class.php:334
1273
+ msgctxt "Label to select a date for a scheduling rule"
1274
+ msgid "Date"
1275
+ msgstr "Datum"
1276
+
1277
+ #: includes/Settings.class.php:335
1278
+ msgctxt "Label to select a time slot for a scheduling rule"
1279
+ msgid "Time"
1280
+ msgstr "Zeit"
1281
+
1282
+ #: includes/Settings.class.php:336
1283
+ msgctxt "Label to set a scheduling rule to last all day"
1284
+ msgid "All day"
1285
+ msgstr "Ganztägig"
1286
+
1287
+ #: includes/Settings.class.php:337
1288
+ msgctxt "Label for the starting time of a scheduling rule"
1289
+ msgid "Start"
1290
+ msgstr "Startzeit"
1291
+
1292
+ #: includes/Settings.class.php:338
1293
+ msgctxt "Label for the ending time of a scheduling rule"
1294
+ msgid "End"
1295
+ msgstr "Endzeit"
1296
+
1297
+ #: includes/Settings.class.php:339
1298
+ #, c-format
1299
+ msgctxt "Prompt displayed when a scheduling rule is set without any time restrictions"
1300
+ msgid "All day long. Want to %sset a time slot%s?"
1301
+ msgstr "Ganztägig. Wollen Sie eine %sZeitdauer%s festlegen?"
1302
+
1303
+ #: includes/Settings.class.php:340
1304
+ msgctxt "Toggle a scheduling rule open and closed"
1305
+ msgid "Open and close this rule"
1306
+ msgstr "Öffnen und Schliessen dieser Regel"
1307
+
1308
+ #: includes/Settings.class.php:341
1309
+ msgctxt "Delete a scheduling rule"
1310
+ msgid "Delete rule"
1311
+ msgstr "Regel löschen"
1312
+
1313
+ #: includes/Settings.class.php:343
1314
+ msgctxt ""
1315
+ "Brief default description of a scheduling rule when no weekdays or weeks are "
1316
+ "included in the rule"
1317
+ msgid "Never"
1318
+ msgstr "Nie"
1319
+
1320
+ #: includes/Settings.class.php:344
1321
+ msgctxt ""
1322
+ "Brief default description of a scheduling rule when all the weekdays/weeks "
1323
+ "are included in the rule"
1324
+ msgid "Every day"
1325
+ msgstr "Täglich"
1326
+
1327
+ #: includes/Settings.class.php:345
1328
+ #, c-format
1329
+ msgctxt ""
1330
+ "Brief default description of a scheduling rule when some weekdays are "
1331
+ "included on only some weeks of the month. %s should be left alone and will "
1332
+ "be replaced by a comma-separated list of days and weeks in the following "
1333
+ "format: M, T, W on the first, second week of the month"
1334
+ msgid "%s on the %s week of the month"
1335
+ msgstr "%s der %s Wochen des Monats"
1336
+
1337
+ #: includes/Settings.class.php:346
1338
+ #, c-format
1339
+ msgctxt ""
1340
+ "Brief default description of a scheduling rule when some weeks of the month "
1341
+ "are included but all or no weekdays are selected. %s should be left alone "
1342
+ "and will be replaced by a comma-separated list of weeks in the following "
1343
+ "format: First, second week of the month"
1344
+ msgid "%s week of the month"
1345
+ msgstr "%s Woche des Monats"
1346
+
1347
+ #: includes/Settings.class.php:347
1348
+ msgctxt "Brief default description of a scheduling rule when no times are set"
1349
+ msgid "All day"
1350
+ msgstr "Täglich"
1351
+
1352
+ #: includes/Settings.class.php:348
1353
+ msgctxt ""
1354
+ "Brief default description of a scheduling rule when an end time is set but "
1355
+ "no start time. If the end time is 6pm, it will read: Ends at 6pm"
1356
+ msgid "Ends at"
1357
+ msgstr "Endet um"
1358
+
1359
+ #: includes/Settings.class.php:349
1360
+ msgctxt ""
1361
+ "Brief default description of a scheduling rule when a start time is set but "
1362
+ "no end time. If the start time is 6pm, it will read: Starts at 6pm"
1363
+ msgid "Starts at"
1364
+ msgstr "Beginnt um"
1365
+
1366
+ #: includes/Settings.class.php:350
1367
+ msgctxt "Separator between times of a scheduling rule"
1368
+ msgid "&mdash;"
1369
+ msgstr "&mdash;"
1370
+
1371
+ #: includes/Settings.class.php:362
1372
+ msgctxt "Monday abbreviation"
1373
+ msgid "Mo"
1374
+ msgstr "Mo"
1375
+
1376
+ #: includes/Settings.class.php:363
1377
+ msgctxt "Tuesday abbreviation"
1378
+ msgid "Tu"
1379
+ msgstr "Di"
1380
+
1381
+ #: includes/Settings.class.php:364
1382
+ msgctxt "Wednesday abbreviation"
1383
+ msgid "We"
1384
+ msgstr "Mi"
1385
+
1386
+ #: includes/Settings.class.php:365
1387
+ msgctxt "Thursday abbreviation"
1388
+ msgid "Th"
1389
+ msgstr "Do"
1390
+
1391
+ #: includes/Settings.class.php:366
1392
+ msgctxt "Friday abbreviation"
1393
+ msgid "Fr"
1394
+ msgstr "Fr"
1395
+
1396
+ #: includes/Settings.class.php:367
1397
+ msgctxt "Saturday abbreviation"
1398
+ msgid "Sa"
1399
+ msgstr "Sa"
1400
+
1401
+ #: includes/Settings.class.php:368
1402
+ msgctxt "Sunday abbreviation"
1403
+ msgid "Su"
1404
+ msgstr "So"
1405
+
1406
+ #: includes/Settings.class.php:378
1407
+ msgctxt "Brief default description of a scheduling exception when no times are set"
1408
+ msgid "Closed all day"
1409
+ msgstr "Ganzer Tag geschlossen"
1410
+
1411
+ #: includes/WP_List_Table.BookingsTable.class.php:137
1412
+ #: includes/WP_List_Table.BookingsTable.class.php:139
1413
+ msgctxt ""
1414
+ "No date limit in a date range, eg 2014-* would mean any date from 2014 or "
1415
+ "after"
1416
+ msgid "*"
1417
+ msgstr "*"
1418
+
1419
+ #: includes/WP_List_Table.BookingsTable.class.php:138
1420
+ msgctxt "Separator between two dates in a date range"
1421
+ msgid "&mdash;"
1422
+ msgstr "&mdash;"
1423
+
1424
+ #: includes/WP_List_Table.BookingsTable.class.php:344
1425
+ msgctxt "Status label for bookings put in the trash"
1426
+ msgid "Trash"
1427
+ msgstr "Mülleimer"
1428
+
1429
+ #: includes/WP_List_Table.BookingsTable.class.php:691
1430
+ #, c-format
1431
+ msgctxt ""
1432
+ "Indicates which booking status is currently being filtered in the list of "
1433
+ "bookings."
1434
+ msgid "You're viewing bookings that have been marked as %s."
1435
+ msgstr "Sie sehen eine Tischreservation die als %s markiert wurde."
1436
+
1437
+ #: includes/WP_List_Table.BookingsTable.class.php:696
1438
+ #, c-format
1439
+ msgctxt "Notification of booking date range, eg - bookings from 2014-12-02-2014-12-05"
1440
+ msgid "Only bookings from %s are being shown."
1441
+ msgstr "Es werden nur Tischreservationen im Zeitraum %s angezeigt."
languages/restaurant-reservations-es_CL.mo ADDED
Binary file
languages/restaurant-reservations-es_CL.po ADDED
@@ -0,0 +1,1201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Restaurant Reservations\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: Thu Jul 17 2014 15:43:57 GMT+0100 (GMT Daylight Time)\n"
6
+ "PO-Revision-Date: Tue Sep 30 2014 20:46:45 GMT-0300 (CLST)\n"
7
+ "Last-Translator: admin <user@example.com>\n"
8
+ "Language-Team: \n"
9
+ "Language: Spanish (Chile)\n"
10
+ "Plural-Forms: nplurals=2; plural=n != 1\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Poedit-Basepath: .\n"
16
+ "X-Poedit-SearchPath-0: ..\n"
17
+ "X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
18
+ "__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
19
+ "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
20
+ "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
21
+ "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
22
+ "X-Generator: Loco - https://localise.biz/\n"
23
+ "X-Loco-Target-Locale: es_CL"
24
+
25
+ #: ../includes/Settings.class.php:634
26
+ msgid "The email subject a user should receive when their booking has been rejected."
27
+ msgstr ""
28
+ "El asunto del mensaje que el usuario debe recibir cuando su Reserva ha sido "
29
+ "rechazada."
30
+
31
+ #: ../includes/Settings.class.php:645
32
+ msgid "Rejected Email"
33
+ msgstr "Mensaje rechazado"
34
+
35
+ #: ../includes/Settings.class.php:646
36
+ msgid "Enter the email a user should receive when their booking has been rejected."
37
+ msgstr ""
38
+ "Ingrese el mensaje que el usuario debe recibir cuando su Reserva ha sido "
39
+ "rechazada."
40
+
41
+ #: ../includes/template-functions.php:84
42
+ msgid "Book a table"
43
+ msgstr "Reservar una mesa"
44
+
45
+ #: ../includes/template-functions.php:89 ../includes/WP_List_Table.BookingsTable.
46
+ #: class.php:267 ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.
47
+ #: class.php:365
48
+ msgid "Date"
49
+ msgstr "Fecha"
50
+
51
+ #: ../includes/template-functions.php:96
52
+ msgid "Time"
53
+ msgstr "Hora"
54
+
55
+ #: ../includes/template-functions.php:103 ../includes/WP_List_Table.BookingsTable.
56
+ #: class.php:268
57
+ msgid "Party"
58
+ msgstr "Invitados"
59
+
60
+ #: ../includes/template-functions.php:110
61
+ msgid "Contact Details"
62
+ msgstr "Detalles del contacto\n"
63
+
64
+ #: ../includes/template-functions.php:115 ../includes/WP_List_Table.BookingsTable.
65
+ #: class.php:269
66
+ msgid "Name"
67
+ msgstr "Nombre"
68
+
69
+ #: ../includes/template-functions.php:122 ../includes/WP_List_Table.BookingsTable.
70
+ #: class.php:270
71
+ msgid "Email"
72
+ msgstr "correo"
73
+
74
+ #: ../includes/template-functions.php:129 ../includes/WP_List_Table.BookingsTable.
75
+ #: class.php:271
76
+ msgid "Phone"
77
+ msgstr "Teléfono"
78
+
79
+ #: ../includes/template-functions.php:135
80
+ msgid "Add a Message"
81
+ msgstr "Añadir un mensaje"
82
+
83
+ #: ../includes/template-functions.php:141 ../includes/WP_List_Table.BookingsTable.
84
+ #: class.php:272
85
+ msgid "Message"
86
+ msgstr "Mensaje"
87
+
88
+ #: ../includes/template-functions.php:146
89
+ msgid "Request Booking"
90
+ msgstr "Solicitar Reserva"
91
+
92
+ #: ../includes/WP_List_Table.BookingsTable.class.php:172 ..
93
+ #: includes/WP_List_Table.BookingsTable.class.php:235
94
+ msgid "All"
95
+ msgstr "todo"
96
+
97
+ #: ../includes/WP_List_Table.BookingsTable.class.php:173
98
+ msgid "Today"
99
+ msgstr "Hoy"
100
+
101
+ #: ../includes/WP_List_Table.BookingsTable.class.php:174
102
+ msgid "Upcoming"
103
+ msgstr "Próximo"
104
+
105
+ #: ../includes/WP_List_Table.BookingsTable.class.php:180
106
+ msgctxt "Separator between two dates in a date range"
107
+ msgid "&mdash;"
108
+ msgstr "&mdash;"
109
+
110
+ #: ../includes/WP_List_Table.BookingsTable.class.php:192
111
+ msgid "Start Date:"
112
+ msgstr "Fecha de inicio:"
113
+
114
+ #: ../includes/WP_List_Table.BookingsTable.class.php:193
115
+ msgid "Start Date"
116
+ msgstr "Fecha de inicio"
117
+
118
+ #: ../includes/WP_List_Table.BookingsTable.class.php:194
119
+ msgid "End Date:"
120
+ msgstr "Fecha de termino:"
121
+
122
+ #: ../includes/WP_List_Table.BookingsTable.class.php:195
123
+ msgid "End Date"
124
+ msgstr "Fecha de termino"
125
+
126
+ #: ../includes/WP_List_Table.BookingsTable.class.php:196
127
+ msgid "Apply"
128
+ msgstr "Aplicar"
129
+
130
+ #: ../includes/WP_List_Table.BookingsTable.class.php:198
131
+ msgid "Clear Filter"
132
+ msgstr "Limpiar filtro"
133
+
134
+ #: ../includes/WP_List_Table.BookingsTable.class.php:236
135
+ msgid "Pending"
136
+ msgstr "Pendiente"
137
+
138
+ #: ../includes/WP_List_Table.BookingsTable.class.php:237
139
+ msgid "Confirmed"
140
+ msgstr "Confirmada"
141
+
142
+ #: ../includes/WP_List_Table.BookingsTable.class.php:238
143
+ msgid "Closed"
144
+ msgstr "Cerrada"
145
+
146
+ #: ../includes/WP_List_Table.BookingsTable.class.php:239
147
+ msgid "Trash"
148
+ msgstr "Papelera"
149
+
150
+ #: ../includes/WP_List_Table.BookingsTable.class.php:273
151
+ msgid "Status"
152
+ msgstr "Estado"
153
+
154
+ #: ../includes/WP_List_Table.BookingsTable.class.php:324
155
+ msgctxt "Status label for bookings put in the trash"
156
+ msgid "Trash"
157
+ msgstr "Desechado"
158
+
159
+ #: ../includes/WP_List_Table.BookingsTable.class.php:356
160
+ msgid "Delete"
161
+ msgstr "Eliminar"
162
+
163
+ #: ../includes/WP_List_Table.BookingsTable.class.php:357
164
+ msgid "Set To Confirmed"
165
+ msgstr "Confirmada"
166
+
167
+ #: ../includes/WP_List_Table.BookingsTable.class.php:358
168
+ msgid "Set To Pending Review"
169
+ msgstr "Pendiente de revisar"
170
+
171
+ #: ../includes/WP_List_Table.BookingsTable.class.php:359
172
+ msgid "Set To Closed"
173
+ msgstr "Cerrarda"
174
+
175
+ #: ../includes/WP_List_Table.BookingsTable.class.php:471
176
+ #, php-format
177
+ msgid "%d booking deleted successfully."
178
+ msgid_plural "%d bookings deleted successfully."
179
+ msgstr[0] "%d Reserva eliminada exitosamente."
180
+ msgstr[1] "%d Reservas eliminadas exitosamente."
181
+
182
+ #: ../includes/WP_List_Table.BookingsTable.class.php:474
183
+ #, php-format
184
+ msgid "%d booking confirmed."
185
+ msgid_plural "%d bookings confirmed."
186
+ msgstr[0] "%d Reserva confirmada."
187
+ msgstr[1] "%d Reservas confirmadas."
188
+
189
+ #: ../includes/WP_List_Table.BookingsTable.class.php:477
190
+ #, php-format
191
+ msgid "%d booking set to pending."
192
+ msgid_plural "%d bookings set to pending."
193
+ msgstr[0] "%d Reserva marcada pendiente."
194
+ msgstr[1] "%d Reservas marcadas pendiente."
195
+
196
+ #: ../includes/WP_List_Table.BookingsTable.class.php:480
197
+ #, php-format
198
+ msgid "%d booking closed."
199
+ msgid_plural "%d bookings closed."
200
+ msgstr[0] "%d Reserva cerrada."
201
+ msgstr[1] "%d Reservas cerradas."
202
+
203
+ #: ../includes/WP_List_Table.BookingsTable.class.php:492
204
+ #, php-format
205
+ msgid "%d booking had errors and could not be processed."
206
+ msgid_plural "%d bookings had errors and could not be processed."
207
+ msgstr[0] "%d Reserva contiene errores y no podrá ser procesada."
208
+ msgstr[1] "%d Reservas contienen errores y no podrán ser procesadas."
209
+
210
+ #: ../includes/WP_Widget.BookingFormWidget.class.php:25
211
+ msgid "Booking Form"
212
+ msgstr "Formulario de Reservas"
213
+
214
+ #: ../includes/WP_Widget.BookingFormWidget.class.php:26
215
+ msgid "Display a form to accept bookings."
216
+ msgstr "Mostrar un formulario para aceptar Reservas."
217
+
218
+ #: ../includes/WP_Widget.BookingFormWidget.class.php:64
219
+ msgid "Title"
220
+ msgstr "Título"
221
+
222
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:266
223
+ msgid "Add new scheduling rule"
224
+ msgstr "Agregar nueva regla de agendamiento"
225
+
226
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:293 ..
227
+ #: lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:306
228
+ msgctxt "Format of a scheduling rule"
229
+ msgid "Weekly"
230
+ msgstr "Semanal"
231
+
232
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:295 ..
233
+ #: lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:314
234
+ msgctxt "Format of a scheduling rule"
235
+ msgid "Monthly"
236
+ msgstr "Mensual"
237
+
238
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:297 ..
239
+ #: lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:322
240
+ msgctxt "Format of a scheduling rule"
241
+ msgid "Date"
242
+ msgstr "Fecha"
243
+
244
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:333
245
+ msgctxt "Label for selecting days of the week in a scheduling rule"
246
+ msgid "Days of the week"
247
+ msgstr "Días de la semana"
248
+
249
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:349
250
+ msgctxt "Label for selecting weeks of the month in a scheduling rule"
251
+ msgid "Weeks of the month"
252
+ msgstr "Semanas del mes"
253
+
254
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:380
255
+ msgctxt "Label to select time slot for a scheduling rule"
256
+ msgid "Time"
257
+ msgstr "Hora"
258
+
259
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:385
260
+ msgctxt "Label to set a scheduling rule to last all day"
261
+ msgid "All day"
262
+ msgstr "Todo el día"
263
+
264
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:394
265
+ msgctxt "Label for the starting time of a scheduling rule"
266
+ msgid "Start"
267
+ msgstr "Inicio"
268
+
269
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:402
270
+ msgctxt "Label for the ending time of a scheduling rule"
271
+ msgid "End"
272
+ msgstr "Fin"
273
+
274
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:411
275
+ msgctxt "Prompt displayed when a scheduling rule is set without any time restrictions."
276
+ msgid ""
277
+ "All day long. Want to <a href=\"#\" data-format=\"time-slot\">set a time "
278
+ "slot</a>?"
279
+ msgstr ""
280
+ "Durante todo el día. \n"
281
+ "¿Desea <a href=\"#\" data-format=\"time-slot\">crear un rango horario</a>?"
282
+
283
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:430 ..
284
+ #: lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:433
285
+ msgid "Open and close this rule"
286
+ msgstr "Abrir y cerrar esta regla"
287
+
288
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:436
289
+ msgid "Delete rule"
290
+ msgstr "Borrar regla"
291
+
292
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:439
293
+ msgid "Delete scheduling rule"
294
+ msgstr "Borrar regla de agendamiento"
295
+
296
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:523
297
+ msgctxt ""
298
+ "Brief default description of a scheduling rule when no weekdays or weeks are "
299
+ "included in the rule."
300
+ msgid "Never"
301
+ msgstr "Nunca"
302
+
303
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:524
304
+ msgctxt ""
305
+ "Brief default description of a scheduling rule when all the weekdays/weeks "
306
+ "are included in the rule."
307
+ msgid "Every day"
308
+ msgstr "Cada día"
309
+
310
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:525
311
+ msgctxt ""
312
+ "Brief default description of a scheduling rule when some weekdays are "
313
+ "included on only some weeks of the month. The {days} and {weeks} bits should "
314
+ "be left alone and will be replaced by a comma-separated list of days (the "
315
+ "first one) and weeks (the second one) in the following format: M, T, W on "
316
+ "the first, second week of the month"
317
+ msgid "{days} on the {weeks} week of the month"
318
+ msgstr "{dias} en la {weeks} semana del mes"
319
+
320
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:526
321
+ msgctxt ""
322
+ "Brief description of a scheduling rule when some weeks of the month are "
323
+ "included but all or no weekdays are selected. {weeks} should be left alone "
324
+ "and will be replaced by a comma-separated list of weeks (the second one) in "
325
+ "the following format: First, second week of the month"
326
+ msgid "{weeks} week of the month"
327
+ msgstr "{weeks} semana del mes"
328
+
329
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:527
330
+ msgctxt "Brief default description of a scheduling rule when no times are set"
331
+ msgid "All day"
332
+ msgstr "Todo el día"
333
+
334
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:528
335
+ msgctxt ""
336
+ "Brief default description of a scheduling rule when an end time is set but "
337
+ "no start time. If the end time is 6pm, it will read: Ends at 6pm."
338
+ msgid "Ends at"
339
+ msgstr "Finaliza a las "
340
+
341
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:529
342
+ msgctxt ""
343
+ "Brief default description of a scheduling rule when a start time is set but "
344
+ "no end time. If the start time is 6pm, it will read: Starts at 6pm."
345
+ msgid "Starts at"
346
+ msgstr "Inicia a las "
347
+
348
+ #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:530
349
+ msgctxt "Default separator between times of a scheduling rule."
350
+ msgid "&mdash;"
351
+ msgstr "&mdash;"
352
+
353
+ #: ../includes/Settings.class.php:609
354
+ msgid "Confirmed Email Subject"
355
+ msgstr "Asunto del mensaje de confirmación"
356
+
357
+ #: ../includes/Settings.class.php:610
358
+ msgid ""
359
+ "The email subject a user should receive when their booking has been "
360
+ "confirmed."
361
+ msgstr ""
362
+ "El asunto en el mensaje que el usuario debe recibir cuando su Reserva ha "
363
+ "sido confirmada."
364
+
365
+ #: ../includes/Settings.class.php:621
366
+ msgid "Confirmed Email"
367
+ msgstr "Mensaje de Confirmación"
368
+
369
+ #: ../includes/Settings.class.php:622
370
+ msgid "Enter the email a user should receive when their booking has been confirmed."
371
+ msgstr ""
372
+ "Ingrese el mensaje que el usuario debe recibir cuando su Reserva ha sido "
373
+ "confirmada."
374
+
375
+ #: ../includes/Settings.class.php:633
376
+ msgid "Rejected Email Subject"
377
+ msgstr "Asunto del mensaje de rechazo"
378
+
379
+ #: ../restaurant-reservations.php:127
380
+ msgid "Booking Manager"
381
+ msgstr "Administrador de Reservas"
382
+
383
+ #: ../restaurant-reservations.php:155
384
+ msgctxt "Title of admin page that lists bookings"
385
+ msgid "Bookings"
386
+ msgstr "Reservas [Titulo de la pagina administrativa que lista las reservas]"
387
+
388
+ #: ../restaurant-reservations.php:156
389
+ msgctxt "Title of bookings admin menu item"
390
+ msgid "Bookings"
391
+ msgstr "Reservas [Titulo de la opción de menú para la administración de reservas]"
392
+
393
+ #: ../restaurant-reservations.php:178
394
+ msgid "Restaurant Bookings"
395
+ msgstr "Reservas para Restaurant"
396
+
397
+ #: ../restaurant-reservations.php:279
398
+ msgid "View the help documentation for Restaurant Reservations"
399
+ msgstr "Ver la documentación de ayuda para la aplicación"
400
+
401
+ #: ../restaurant-reservations.php:279
402
+ msgid "Help"
403
+ msgstr "Ayuda"
404
+
405
+ #: ../includes/Booking.class.php:154
406
+ msgid "Please enter the date you would like to book."
407
+ msgstr "Por favor, ingrese la fecha en que desea hacer la reserva."
408
+
409
+ #: ../includes/Booking.class.php:164
410
+ msgid ""
411
+ "The date you entered is not valid. Please select from one of the dates in "
412
+ "the calendar."
413
+ msgstr ""
414
+ "La fecha ingresada no es válida, por favor seleccione una fecha disponible "
415
+ "en el calendario."
416
+
417
+ #: ../includes/Booking.class.php:175
418
+ msgid "Please enter the time you would like to book."
419
+ msgstr "Por favor ingrese la hora en que desea hacer la reserva."
420
+
421
+ #: ../includes/Booking.class.php:185
422
+ msgid ""
423
+ "The time you entered is not valid. Please select from one of the times "
424
+ "provided."
425
+ msgstr ""
426
+ "La hora ingresada no es válida, por favor seleccione una de las horas "
427
+ "disponibles."
428
+
429
+ #: ../includes/Booking.class.php:204
430
+ #, php-format
431
+ msgid "Sorry, bookings can not be made more than %s days in advance."
432
+ msgstr "Disculpe, las reservas no se pueden crear con más de %s dias de anticipación."
433
+
434
+ #: ../includes/Booking.class.php:215
435
+ msgid "Sorry, bookings can not be made in the past."
436
+ msgstr "Disculpe, no se pueden crear reservas en el pasado."
437
+
438
+ #: ../includes/Booking.class.php:223
439
+ #, php-format
440
+ msgid "Sorry, bookings must be made more than %s days in advance."
441
+ msgstr "Disculpe, las reservas deben ser creadas con más de %s dias de anticipación. "
442
+
443
+ #: ../includes/Booking.class.php:225
444
+ #, php-format
445
+ msgid "Sorry, bookings must be made more than %s hours in advance."
446
+ msgstr "Disculpe, las reservas deben ser creadas con más de %s horas de anticipación."
447
+
448
+ #: ../includes/Booking.class.php:227
449
+ #, php-format
450
+ msgid "Sorry, bookings must be made more than %s mings in advance."
451
+ msgstr ""
452
+ "Disculpe, las reservas deben ser creadas con más de %s minutos de "
453
+ "anticipación."
454
+
455
+ #: ../includes/Booking.class.php:266
456
+ msgid "Sorry, no bookings are being accepted then."
457
+ msgstr "Disculpe, no se están aceptando reservas."
458
+
459
+ #: ../includes/Booking.class.php:318
460
+ msgid "Sorry, no bookings are being accepted on that date."
461
+ msgstr "Disculpe, no se están aceptando reservas para esa fecha."
462
+
463
+ #: ../includes/Booking.class.php:324
464
+ msgid "Sorry, no bookings are being accepted at that time."
465
+ msgstr "Disculpe, no se están aceptando reservas para esa hora."
466
+
467
+ #: ../includes/Booking.class.php:346
468
+ msgid "Please enter a name for this booking."
469
+ msgstr "Por favor ingrese un nombre para esta reserva."
470
+
471
+ #: ../includes/Booking.class.php:356
472
+ msgid "Please let us know how many people will be in your party."
473
+ msgstr "Por favor díganos cuántas personas ocuparán su reserva."
474
+
475
+ #: ../includes/Booking.class.php:370
476
+ #, php-format
477
+ msgid "We only accept bookings for parties of up to %d people."
478
+ msgstr "Solo aceptamos reservas que incluyan hasta %d personas."
479
+
480
+ #: ../includes/Booking.class.php:381
481
+ msgid "Please enter an email address so we can confirm your booking."
482
+ msgstr ""
483
+ "Por favor ingrese una dirección de e-mail a donde enviaremos la confirmación "
484
+ "de su reserva."
485
+
486
+ #: ../includes/CustomPostTypes.class.php:38 ../includes/CustomPostTypes.class.php:
487
+ #: 40 ../includes/CustomPostTypes.class.php:41 ../includes/WP_List_Table.
488
+ #: BookingsTable.class.php:76
489
+ msgid "Bookings"
490
+ msgstr "Reservas"
491
+
492
+ #: ../includes/CustomPostTypes.class.php:39 ../includes/WP_List_Table.
493
+ #: BookingsTable.class.php:75
494
+ msgid "Booking"
495
+ msgstr "Reserva"
496
+
497
+ #: ../includes/CustomPostTypes.class.php:42
498
+ msgid "Add New"
499
+ msgstr "Agregar"
500
+
501
+ #: ../includes/CustomPostTypes.class.php:43
502
+ msgid "Add New Booking"
503
+ msgstr "Agregar nueva Reserva"
504
+
505
+ #: ../includes/CustomPostTypes.class.php:44
506
+ msgid "Edit Booking"
507
+ msgstr "Editar Reserva"
508
+
509
+ #: ../includes/CustomPostTypes.class.php:45
510
+ msgid "New Booking"
511
+ msgstr "Nueva Reserva"
512
+
513
+ #: ../includes/CustomPostTypes.class.php:46
514
+ msgid "View Booking"
515
+ msgstr "Ver Reserva"
516
+
517
+ #: ../includes/CustomPostTypes.class.php:47
518
+ msgid "Search Bookings"
519
+ msgstr "Buscar Reservas"
520
+
521
+ #: ../includes/CustomPostTypes.class.php:48
522
+ msgid "No bookings found"
523
+ msgstr "No se encontraron Reservas"
524
+
525
+ #: ../includes/CustomPostTypes.class.php:49
526
+ msgid "No bookings found in trash"
527
+ msgstr "No se encontraron Reservas en la papelera"
528
+
529
+ #: ../includes/CustomPostTypes.class.php:50
530
+ msgid "All Bookings"
531
+ msgstr "Todas las Reservas"
532
+
533
+ #: ../includes/CustomPostTypes.class.php:80
534
+ msgctxt "Booking status when it is pending review"
535
+ msgid "Pending"
536
+ msgstr ""
537
+ "Pendiente [Reserva que se encuentra sin\n"
538
+ " revisar] "
539
+
540
+ #: ../includes/CustomPostTypes.class.php:86
541
+ msgctxt "Booking status for a confirmed booking"
542
+ msgid "Confirmed"
543
+ msgstr "Confirmada [Reserva que se encuentra confirmada] "
544
+
545
+ #: ../includes/CustomPostTypes.class.php:93
546
+ #, php-format
547
+ msgid "Confirmed <span class=\"count\">(%s)</span>"
548
+ msgid_plural "Confirmed <span class=\"count\">(%s)</span>"
549
+ msgstr[0] "Confirmada <span class=\"count\">(%s)</span>"
550
+ msgstr[1] "Confirmadas <span class=\"count\">(%s)</span>"
551
+
552
+ #: ../includes/CustomPostTypes.class.php:97
553
+ msgctxt "Booking status for a closed booking"
554
+ msgid "Closed"
555
+ msgstr "Cerrada"
556
+
557
+ #: ../includes/CustomPostTypes.class.php:104
558
+ #, php-format
559
+ msgid "Closed <span class=\"count\">(%s)</span>"
560
+ msgid_plural "Closed <span class=\"count\">(%s)</span>"
561
+ msgstr[0] ""
562
+ "Cerrada \n"
563
+ "<span class=\"count\">(%s)</span>"
564
+ msgstr[1] ""
565
+ "Cerradas \n"
566
+ "<span class=\"count\">(%s)</span>"
567
+
568
+ #: ../includes/Notification.class.php:87
569
+ msgid "View pending bookings"
570
+ msgstr "Revisar Reservas pendientes"
571
+
572
+ #: ../includes/Notification.class.php:88
573
+ msgid "Confirm this booking"
574
+ msgstr "Confirmar esta Reserva"
575
+
576
+ #: ../includes/Notification.class.php:89
577
+ msgid "Reject this booking"
578
+ msgstr "Rechazar esta Reserva"
579
+
580
+ #: ../includes/Settings.class.php:83
581
+ msgid ""
582
+ "Thanks, your booking request is waiting to be confirmed. Updates will be "
583
+ "sent to the email address you provided."
584
+ msgstr ""
585
+ "Gracias, su Reserva queda en espera de ser confirmada. Le notificaremos a "
586
+ "la dirección email que usted nos indicó."
587
+
588
+ #: ../includes/Settings.class.php:84
589
+ msgctxt ""
590
+ "Default date format for display. Must match formatting rules at http://amsul."
591
+ "ca/pickadate.js/date.htm#formatting-rules"
592
+ msgid "mmmm d, yyyy"
593
+ msgstr "mmmm d, yyyy"
594
+
595
+ #: ../includes/Settings.class.php:85
596
+ msgctxt ""
597
+ "Default time format for display. Must match formatting rules at http://amsul."
598
+ "ca/pickadate.js/time.htm#formats"
599
+ msgid "h:i A"
600
+ msgstr "h:i A"
601
+
602
+ #: ../includes/Settings.class.php:86
603
+ msgctxt "Default interval in minutes when selecting a time."
604
+ msgid "30"
605
+ msgstr "15"
606
+
607
+ #: ../includes/Settings.class.php:96
608
+ msgctxt "Default email subject for admin notifications of new bookings"
609
+ msgid "New Booking Request"
610
+ msgstr "Nueva solicitud de Reserva"
611
+
612
+ #: ../includes/Settings.class.php:97
613
+ msgctxt ""
614
+ "Default email sent to the admin when a new booking request is made. The tags "
615
+ "in {brackets} will be replaced by the appropriate content and should be left "
616
+ "in place. HTML is allowed, but be aware that many email clients do not "
617
+ "handle HTML very well."
618
+ msgid ""
619
+ "A new booking request has been made at {site_name}:\n"
620
+ "\n"
621
+ "{user_name}\n"
622
+ "{party} people\n"
623
+ "{date}\n"
624
+ "\n"
625
+ "{bookings_link}\n"
626
+ "{confirm_link}\n"
627
+ "{close_link}\n"
628
+ "\n"
629
+ "&nbsp;\n"
630
+ "\n"
631
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
632
+ msgstr ""
633
+ "Una nueva solicitud de reserva ha sido creada en {site_name}:\n"
634
+ "\n"
635
+ "Nombre: {user_name}\n"
636
+ "participantes: {party} \n"
637
+ "Fecha: {date}\n"
638
+ "\n"
639
+ "{bookings_link} {confirm_link} {close_link}\n"
640
+ "\n"
641
+ "\n"
642
+ "&nbsp;\n"
643
+ "\n"
644
+ "<em>Éste mensaje fué enviado por {site_link} a las {current_time}.</em>"
645
+
646
+ #: ../includes/Settings.class.php:115
647
+ #, php-format
648
+ msgctxt ""
649
+ "Default email subject sent to user when they request a booking. %s will be "
650
+ "replaced by the website name"
651
+ msgid "Your booking at %s is pending"
652
+ msgstr "Su Reserva para %s se encuentra pendiente"
653
+
654
+ #: ../includes/Settings.class.php:116
655
+ msgctxt ""
656
+ "Default email sent to users when they make a new booking request. The tags "
657
+ "in {brackets} will be replaced by the appropriate content and should be left "
658
+ "in place. HTML is allowed, but be aware that many email clients do not "
659
+ "handle HTML very well."
660
+ msgid ""
661
+ "Thanks {user_name},\n"
662
+ "\n"
663
+ "Your booking request is <strong>waiting to be confirmed</strong>.\n"
664
+ "\n"
665
+ "Give us a few moments to make sure that we've got space for you. You will "
666
+ "receive another email from us soon. If this request was made outside of our "
667
+ "normal working hours, we may not be able to confirm it until we're open "
668
+ "again.\n"
669
+ "\n"
670
+ "<strong>Your request details:</strong>\n"
671
+ "{user_name}\n"
672
+ "{party} people\n"
673
+ "{date}\n"
674
+ "\n"
675
+ "&nbsp;\n"
676
+ "\n"
677
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
678
+ msgstr ""
679
+ "Gracias {user_name},\n"
680
+ "\n"
681
+ "Su solicitud de Reserva se encuentra <strong>en espera de ser "
682
+ "confirmada</strong>.\n"
683
+ "\n"
684
+ "Dénos un momento para estar seguros de que tenemos espacio para usted. "
685
+ "Pronto recibirá otro mensaje de correo nuestro. Si su solicitud fué creada "
686
+ "fuera de nuestro horario normal de trabajo no podremos confirmarla hasta que "
687
+ "abramos nuevamente.\n"
688
+ "\n"
689
+ "<strong>Detalles de su solicitud:</strong>\n"
690
+ "\n"
691
+ "Nombre: {user_name}\n"
692
+ "Participantes: {party}\n"
693
+ "Fecha: {date}\n"
694
+ "\n"
695
+ "&nbsp;\n"
696
+ "\n"
697
+ "\n"
698
+ "\n"
699
+ "<em>Éste mensaje fué enviado por {site_link} a las {current_time}.</em>\n"
700
+
701
+ #: ../includes/Settings.class.php:135
702
+ #, php-format
703
+ msgctxt ""
704
+ "Default email subject sent to user when their booking is confirmed. %s will "
705
+ "be replaced by the website name"
706
+ msgid "Your booking at %s is confirmed"
707
+ msgstr "Su Reserva para %s ha sido confirmada"
708
+
709
+ #: ../includes/Settings.class.php:136
710
+ msgctxt ""
711
+ "Default email sent to users when they make a new booking request. The tags "
712
+ "in {brackets} will be replaced by the appropriate content and should be left "
713
+ "in place. HTML is allowed, but be aware that many email clients do not "
714
+ "handle HTML very well."
715
+ msgid ""
716
+ "Hi {user_name},\n"
717
+ "\n"
718
+ "Your booking request has been <strong>confirmed</strong>. We look forward to "
719
+ "seeing you soon.\n"
720
+ "\n"
721
+ "<strong>Your booking:</strong>\n"
722
+ "{user_name}\n"
723
+ "{party} people\n"
724
+ "{date}\n"
725
+ "\n"
726
+ "&nbsp;\n"
727
+ "\n"
728
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
729
+ msgstr ""
730
+ "Hola {user_name}\n"
731
+ "\n"
732
+ "Su solicitud de Reserva ha sido <strong>confirmada</strong>. Esperamos su "
733
+ "visita.\n"
734
+ "\n"
735
+ "<strong>Su Reserva</strong>\n"
736
+ "\n"
737
+ "Nombre: {user_name}\n"
738
+ "Participantes: {party}\n"
739
+ "Fecha: {date}\n"
740
+ "\n"
741
+ "&nbsp;\n"
742
+ "\n"
743
+ "<em>Éste mensaje fué enviado por {site_link} a las {current_time}.</em>"
744
+
745
+ #: ../includes/Settings.class.php:153
746
+ #, php-format
747
+ msgctxt ""
748
+ "Default email subject sent to user when their booking is rejected. %s will "
749
+ "be replaced by the website name"
750
+ msgid "Your booking at %s was not accepted"
751
+ msgstr "Su Reserva para %s ha sido rechazada"
752
+
753
+ #: ../includes/Settings.class.php:154
754
+ msgctxt ""
755
+ "Default email sent to users when they make a new booking request. The tags "
756
+ "in {brackets} will be replaced by the appropriate content and should be left "
757
+ "in place. HTML is allowed, but be aware that many email clients do not "
758
+ "handle HTML very well."
759
+ msgid ""
760
+ "Hi {user_name},\n"
761
+ "\n"
762
+ "Sorry, we could not accomodate your booking request. We're full or not open "
763
+ "at the time you requested:\n"
764
+ "\n"
765
+ "{user_name}\n"
766
+ "{party} people\n"
767
+ "{date}\n"
768
+ "\n"
769
+ "&nbsp;\n"
770
+ "\n"
771
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
772
+ msgstr ""
773
+ "Hola {user_name},\n"
774
+ "\n"
775
+ "Disculpe, no podemos acomodar su solicitud de Reserva para la hora "
776
+ "solicitada.\n"
777
+ "\n"
778
+ "<strong>Su solicitud de Reserva</strong>\n"
779
+ "\n"
780
+ "Nombre: {user_name}\n"
781
+ "Participantes: {party}\n"
782
+ "Fecha: {date}\n"
783
+ "\n"
784
+ "&nbsp;\n"
785
+ "\n"
786
+ "<em>Éste mensaje fué enviado por {site_link} a las {current_time}.</em>\n"
787
+
788
+ #: ../includes/Settings.class.php:218 ../includes/Settings.class.php:219
789
+ msgid "Settings"
790
+ msgstr "Preferencias"
791
+
792
+ #: ../includes/Settings.class.php:231
793
+ msgid "General"
794
+ msgstr "General"
795
+
796
+ #: ../includes/Settings.class.php:242
797
+ msgid "Booking Page"
798
+ msgstr "Pagina de Reservas"
799
+
800
+ #: ../includes/Settings.class.php:243
801
+ msgid ""
802
+ "Select a page on your site to automatically display the booking form and "
803
+ "confirmation message."
804
+ msgstr ""
805
+ "Seleccione una página en su sitio para automáticamente mostrar el formulario "
806
+ "se solicitud de Reserva y el mensaje de confirmación."
807
+
808
+ #: ../includes/Settings.class.php:259
809
+ msgid "Max Party Size"
810
+ msgstr "Cantidad máxima de participantes"
811
+
812
+ #: ../includes/Settings.class.php:260
813
+ msgid ""
814
+ "Set a maximum allowed party size for bookings. Leave it empty to allow "
815
+ "parties of any size."
816
+ msgstr ""
817
+ "Establecer un número máximo permitido de participantes para una Reserva. "
818
+ "Déjelo en blanco para permitir participantes sin límite."
819
+
820
+ #: ../includes/Settings.class.php:261
821
+ msgid "No limit"
822
+ msgstr "Sin límite"
823
+
824
+ #: ../includes/Settings.class.php:271
825
+ msgid "Success Message"
826
+ msgstr "Mensaje exitoso"
827
+
828
+ #: ../includes/Settings.class.php:272
829
+ msgid "Enter the message to display when a booking request is made."
830
+ msgstr "Ingrese el mensaje a mostrar cuando una solicitud de Reserva sea creada."
831
+
832
+ #: ../includes/Settings.class.php:283
833
+ msgid "Date Format"
834
+ msgstr "Formato de fecha"
835
+
836
+ #: ../includes/Settings.class.php:284
837
+ msgid ""
838
+ "Define how the date should appear after it has been selected. <a href=\"http:"
839
+ "//amsul.ca/pickadate.js/date.htm#formatting-rules\">Formatting rules</a>"
840
+ msgstr ""
841
+ "Defina cómo la fecha debe aparecer después de que haya sido seleccionada. \n"
842
+ "<a href=\"http://amsul.ca/pickadate.js/date.htm#formatting-rules\">Reglas de "
843
+ "formateo</a>"
844
+
845
+ #: ../includes/Settings.class.php:295
846
+ msgid "Time Format"
847
+ msgstr "Formato de hora"
848
+
849
+ #: ../includes/Settings.class.php:296
850
+ msgid ""
851
+ "Define how the time should appear after it has been selected. <a href=\"http:"
852
+ "//amsul.ca/pickadate.js/time.htm#formatting-rules\">Formatting rules</a>"
853
+ msgstr ""
854
+ "Defina cómo la hora debe aparecer después de que haya sido seleccionada. \n"
855
+ "<a href=\"http://amsul.ca/pickadate.js/time.htm#formatting-rules\">Reglas de "
856
+ "formateo</a>"
857
+
858
+ #: ../includes/Settings.class.php:309
859
+ msgid "Language"
860
+ msgstr "Lenguaje"
861
+
862
+ #: ../includes/Settings.class.php:310
863
+ msgid ""
864
+ "Select a language to use for the booking form datepicker if it is different "
865
+ "than your WordPress language setting."
866
+ msgstr ""
867
+ "Seleccione el lenguaje a usar para el selector de fechas en el formulario de "
868
+ "solicitud de Reservas si éste es diferente que el lenguaje establecido para "
869
+ "WordPress."
870
+
871
+ #: ../includes/Settings.class.php:320
872
+ msgid "Booking Schedule"
873
+ msgstr "Programación de Reservas"
874
+
875
+ #: ../includes/Settings.class.php:331
876
+ msgid "Schedule"
877
+ msgstr "Programación"
878
+
879
+ #: ../includes/Settings.class.php:332
880
+ msgid "Define the weekly schedule during which you accept bookings."
881
+ msgstr "Defina la programación semanal durante la cual se aceptarán Reservas."
882
+
883
+ #: ../includes/Settings.class.php:334
884
+ msgctxt "Monday abbreviation"
885
+ msgid "Mo"
886
+ msgstr "Lun "
887
+
888
+ #: ../includes/Settings.class.php:335
889
+ msgctxt "Tuesday abbreviation"
890
+ msgid "Tu"
891
+ msgstr "Mar"
892
+
893
+ #: ../includes/Settings.class.php:336
894
+ msgctxt "Wednesday abbreviation"
895
+ msgid "We"
896
+ msgstr "Mié"
897
+
898
+ #: ../includes/Settings.class.php:337
899
+ msgctxt "Thursday abbreviation"
900
+ msgid "Th"
901
+ msgstr "Jue"
902
+
903
+ #: ../includes/Settings.class.php:338
904
+ msgctxt "Friday abbreviation"
905
+ msgid "Fr"
906
+ msgstr "Vie"
907
+
908
+ #: ../includes/Settings.class.php:339
909
+ msgctxt "Saturday abbreviation"
910
+ msgid "Sa"
911
+ msgstr "Sáb"
912
+
913
+ #: ../includes/Settings.class.php:340
914
+ msgctxt "Sunday abbreviation"
915
+ msgid "Su"
916
+ msgstr "Dom"
917
+
918
+ #: ../includes/Settings.class.php:355
919
+ msgid "Exceptions"
920
+ msgstr "Exepciones"
921
+
922
+ #: ../includes/Settings.class.php:356
923
+ msgid ""
924
+ "Define special opening hours for holidays, events or other needs. Leave the "
925
+ "time empty if you're closed all day."
926
+ msgstr ""
927
+ "Defina horas de atención especiales para fiestas, eventos u otras "
928
+ "necesidades. Déje la hora en blanco si permanecerá cerrado todo el día."
929
+
930
+ #: ../includes/Settings.class.php:362
931
+ msgctxt "Brief description of a scheduling exception when no times are set"
932
+ msgid "Closed all day"
933
+ msgstr "Cerrado todo el día"
934
+
935
+ #: ../includes/Settings.class.php:373
936
+ msgid "Early Bookings"
937
+ msgstr "Próximas Reservas"
938
+
939
+ #: ../includes/Settings.class.php:374
940
+ msgid "Select how early customers can make their booking."
941
+ msgstr "Seleccione cómo los próximos clientes podrán hacer sus Reservas"
942
+
943
+ #: ../includes/Settings.class.php:377
944
+ msgid "Any time"
945
+ msgstr "Cualquier hora"
946
+
947
+ #: ../includes/Settings.class.php:378
948
+ msgid "Up to 1 day in advance"
949
+ msgstr "Hasta 1 día anticipado"
950
+
951
+ #: ../includes/Settings.class.php:379
952
+ msgid "Up to 1 week in advance"
953
+ msgstr "Hasta 1 semana anticipada"
954
+
955
+ #: ../includes/Settings.class.php:380
956
+ msgid "Up to 2 weeks in advance"
957
+ msgstr "Hasta 2 semanas anticipadas"
958
+
959
+ #: ../includes/Settings.class.php:381
960
+ msgid "Up to 30 days in advance"
961
+ msgstr "Hasta 30 días anticipados"
962
+
963
+ #: ../includes/Settings.class.php:382
964
+ msgid "Up to 90 days in advance"
965
+ msgstr "Hasta 90 dias anticipados"
966
+
967
+ #: ../includes/Settings.class.php:393
968
+ msgid "Late Bookings"
969
+ msgstr "Reservas atrazadas"
970
+
971
+ #: ../includes/Settings.class.php:394
972
+ msgid "Select how late customers can make their booking."
973
+ msgstr "Seleccione cómo los clientes pueden hacer reservas de último momento."
974
+
975
+ #: ../includes/Settings.class.php:397
976
+ msgid "Up to the last minute"
977
+ msgstr "Hasta el último minuto"
978
+
979
+ #: ../includes/Settings.class.php:398
980
+ msgid "At least 15 minutes in advance"
981
+ msgstr "Al menos 15 minutos de anticipo"
982
+
983
+ #: ../includes/Settings.class.php:399
984
+ msgid "At least 30 minutes in advance"
985
+ msgstr "Al menos 30 minutos de anticipo"
986
+
987
+ #: ../includes/Settings.class.php:400
988
+ msgid "At least 45 minutes in advance"
989
+ msgstr "Al menos 45 minutos de anticipo"
990
+
991
+ #: ../includes/Settings.class.php:401
992
+ msgid "At least 1 hour in advance"
993
+ msgstr "Al menos 1 hora de anticipo"
994
+
995
+ #: ../includes/Settings.class.php:402
996
+ msgid "At least 4 hours in advance"
997
+ msgstr "Al menos 4 horas de anticipo"
998
+
999
+ #: ../includes/Settings.class.php:403
1000
+ msgid "At least 1 day in advance"
1001
+ msgstr "Al menos 1 día de anticipo"
1002
+
1003
+ #: ../includes/Settings.class.php:414
1004
+ msgid "Date Pre-selection"
1005
+ msgstr "Pre-selección de fecha"
1006
+
1007
+ #: ../includes/Settings.class.php:415
1008
+ msgid ""
1009
+ "When the booking form is loaded, should it automatically attempt to select a "
1010
+ "valid date?"
1011
+ msgstr ""
1012
+ "Cuando el formulario de Reserva es cargado, éste debe automáticamente "
1013
+ "seleccionar una fecha válida?"
1014
+
1015
+ #: ../includes/Settings.class.php:418
1016
+ msgid "Select today or soonest valid date"
1017
+ msgstr "Seleccione hoy o la fecha válida mas próxima"
1018
+
1019
+ #: ../includes/Settings.class.php:419
1020
+ msgid "Leave empty"
1021
+ msgstr "Dejar en blanco"
1022
+
1023
+ #: ../includes/Settings.class.php:430
1024
+ msgid "Time Interval"
1025
+ msgstr "Intervalo de hora"
1026
+
1027
+ #: ../includes/Settings.class.php:431
1028
+ msgid "Select the number of minutes between each available time."
1029
+ msgstr "Seleccione el número de minutos entre cada hora disponible."
1030
+
1031
+ #: ../includes/Settings.class.php:434
1032
+ msgid "Every 30 minutes"
1033
+ msgstr "Cada 30 minutos"
1034
+
1035
+ #: ../includes/Settings.class.php:435
1036
+ msgid "Every 15 minutes"
1037
+ msgstr "Cada 15 minutos"
1038
+
1039
+ #: ../includes/Settings.class.php:436
1040
+ msgid "Every 10 minutes"
1041
+ msgstr "Cada 10 minutos"
1042
+
1043
+ #: ../includes/Settings.class.php:437
1044
+ msgid "Every 5 minutes"
1045
+ msgstr "Cada 5 minutos"
1046
+
1047
+ #: ../includes/Settings.class.php:446
1048
+ msgid "Notifications"
1049
+ msgstr "Notificaciones"
1050
+
1051
+ #: ../includes/Settings.class.php:457
1052
+ msgid "Reply-To Name"
1053
+ msgstr "Nombre a quién responder"
1054
+
1055
+ #: ../includes/Settings.class.php:458
1056
+ msgid "The name which should appear in the Reply-To field of a notification email"
1057
+ msgstr ""
1058
+ "El nombre que debe aparecer en el campo 'Responder a' del mensaje de "
1059
+ "notificación."
1060
+
1061
+ #: ../includes/Settings.class.php:469
1062
+ msgid "Reply-To Email Address"
1063
+ msgstr "Dirección de correo en 'Responder a' "
1064
+
1065
+ #: ../includes/Settings.class.php:470
1066
+ msgid ""
1067
+ "The email address which should appear in the Reply-To field of a "
1068
+ "notification email."
1069
+ msgstr ""
1070
+ "La dirección de correo que debe aparecer en el campo 'Responder a' del "
1071
+ "mensaje de notificación."
1072
+
1073
+ #: ../includes/Settings.class.php:481
1074
+ msgid "Admin Notification"
1075
+ msgstr "Notificar al administrador"
1076
+
1077
+ #: ../includes/Settings.class.php:482
1078
+ msgid ""
1079
+ "Send an email notification to an administrator when a new booking is "
1080
+ "requested."
1081
+ msgstr ""
1082
+ "Enviar un mensaje de notificación a un administrador cuando una nueva "
1083
+ "Reserva ha sido solicitada."
1084
+
1085
+ #: ../includes/Settings.class.php:492
1086
+ msgid "Admin Email Address"
1087
+ msgstr "Dirección de correo del administrador"
1088
+
1089
+ #: ../includes/Settings.class.php:493
1090
+ msgid "The email address where admin notifications should be sent."
1091
+ msgstr ""
1092
+ "La dirección de correo donde deben enviarse las notificaciones al "
1093
+ "administrador"
1094
+
1095
+ #: ../includes/Settings.class.php:502
1096
+ msgid "Email Templates"
1097
+ msgstr "Plantillas de mensajes"
1098
+
1099
+ #: ../includes/Settings.class.php:516
1100
+ msgid "Template Tags"
1101
+ msgstr "Etiquetas de la plantilla"
1102
+
1103
+ #: ../includes/Settings.class.php:518
1104
+ msgid ""
1105
+ "Use the following tags to automatically add booking information to the "
1106
+ "emails."
1107
+ msgstr ""
1108
+ "Utilice las siguientes etiquetas para automáticamente agregar información de "
1109
+ "la Reserva a los mensajes."
1110
+
1111
+ #: ../includes/Settings.class.php:520
1112
+ msgid "Name of the user who made the booking"
1113
+ msgstr "Nombre del usuario que hizo la Reserva"
1114
+
1115
+ #: ../includes/Settings.class.php:523
1116
+ msgid "Number of people booked"
1117
+ msgstr "Número de personas para la Reserva"
1118
+
1119
+ #: ../includes/Settings.class.php:526
1120
+ msgid "Date and time of the booking"
1121
+ msgstr "Fecha y hora de la Reserva"
1122
+
1123
+ #: ../includes/Settings.class.php:529
1124
+ msgid "Phone number if supplied with the request"
1125
+ msgstr "Número telefónico si fué ingresado en la Reserva"
1126
+
1127
+ #: ../includes/Settings.class.php:532
1128
+ msgid "Message added to the request"
1129
+ msgstr "Mensaje agregado en la Reserva"
1130
+
1131
+ #: ../includes/Settings.class.php:535
1132
+ msgid "A link to the admin panel showing pending bookings"
1133
+ msgstr "Enlace al panel de administración que muestra las Reservas pendientes"
1134
+
1135
+ #: ../includes/Settings.class.php:538
1136
+ msgid "A link to confirm this booking. Only include this in admin notifications"
1137
+ msgstr ""
1138
+ "Enlace para confirmar esta Reserva. Solo incluir éste en las notificaciones "
1139
+ "al administrador."
1140
+
1141
+ #: ../includes/Settings.class.php:541
1142
+ msgid "A link to reject this booking. Only include this in admin notifications"
1143
+ msgstr ""
1144
+ "Enlace para rechazar esta Reserva. Solo incluir éste en las notificaciones "
1145
+ "al administrador."
1146
+
1147
+ #: ../includes/Settings.class.php:544
1148
+ msgid "The name of this website"
1149
+ msgstr "El nombre del sitio web"
1150
+
1151
+ #: ../includes/Settings.class.php:547
1152
+ msgid "A link to this website"
1153
+ msgstr "Enlace a éste sitio web"
1154
+
1155
+ #: ../includes/Settings.class.php:550
1156
+ msgid "Current date and time"
1157
+ msgstr "Fecha y hora actual"
1158
+
1159
+ #: ../includes/Settings.class.php:561
1160
+ msgid "Admin Notification Subject"
1161
+ msgstr "Asunto de la notificación al administrador"
1162
+
1163
+ #: ../includes/Settings.class.php:562
1164
+ msgid "The email subject for admin notifications."
1165
+ msgstr "El asunto del mensaje para las notificaciones al administrador."
1166
+
1167
+ #: ../includes/Settings.class.php:573
1168
+ msgid "Admin Notification Email"
1169
+ msgstr "Mensaje de notificación al administrador"
1170
+
1171
+ #: ../includes/Settings.class.php:574
1172
+ msgid ""
1173
+ "Enter the email an admin should receive when an initial booking request is "
1174
+ "made."
1175
+ msgstr ""
1176
+ "Ingrese el correo del administrador que debe recibir una notificación cuando "
1177
+ "se inicia una solicitud de Reserva."
1178
+
1179
+ #: ../includes/Settings.class.php:585
1180
+ msgid "New Request Email Subject"
1181
+ msgstr "Asunto para el mensaje de nueva solicitud"
1182
+
1183
+ #: ../includes/Settings.class.php:586
1184
+ msgid ""
1185
+ "The email subject a user should receive when they make an initial booking "
1186
+ "request."
1187
+ msgstr ""
1188
+ "El asunto en el mensaje que el usuario debe recibir cuando él crea una "
1189
+ "solicitud de Reserva."
1190
+
1191
+ #: ../includes/Settings.class.php:597
1192
+ msgid "New Request Email"
1193
+ msgstr "Mensaje de nueva solicitud"
1194
+
1195
+ #: ../includes/Settings.class.php:598
1196
+ msgid ""
1197
+ "Enter the email a user should receive when they make an initial booking "
1198
+ "request."
1199
+ msgstr ""
1200
+ "Ingrese el mensaje de correo que el usuario que debe recibir cuando ingrese "
1201
+ "una solicitud de reserva."
languages/restaurant-reservations-nl_NL.MO ADDED
Binary file
languages/{rtbdomain.pot → restaurant-reservations-nl_NL.PO} RENAMED
@@ -1,16 +1,14 @@
1
- # Loco Gettext template
2
- #, fuzzy
3
  msgid ""
4
  msgstr ""
5
  "Project-Id-Version: Restaurant Reservations\n"
6
  "Report-Msgid-Bugs-To: \n"
7
  "POT-Creation-Date: Thu Jul 17 2014 15:43:57 GMT+0100 (GMT Daylight Time)\n"
8
- "POT-Revision-Date: Thu Jul 17 2014 15:44:22 GMT+0100 (GMT Daylight Time)\n"
9
- "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
10
- "Last-Translator: \n"
11
  "Language-Team: \n"
12
- "Language: \n"
13
- "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION\n"
14
  "MIME-Version: 1.0\n"
15
  "Content-Type: text/plain; charset=UTF-8\n"
16
  "Content-Transfer-Encoding: 8bit\n"
@@ -22,984 +20,1088 @@ msgstr ""
22
  "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
23
  "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
24
  "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
25
- "X-Generator: Loco - https://localise.biz/"
 
26
 
27
- #: ../restaurant-reservations.php:127
28
- msgid "Booking Manager"
29
- msgstr ""
30
-
31
- #: ../restaurant-reservations.php:155
32
- msgctxt "Title of admin page that lists bookings"
33
- msgid "Bookings"
34
- msgstr ""
35
-
36
- #: ../restaurant-reservations.php:156
37
- msgctxt "Title of bookings admin menu item"
38
- msgid "Bookings"
39
- msgstr ""
40
-
41
- #: ../restaurant-reservations.php:178
42
- msgid "Restaurant Bookings"
43
- msgstr ""
44
-
45
- #: ../restaurant-reservations.php:279
46
- msgid "View the help documentation for Restaurant Reservations"
47
- msgstr ""
48
 
49
- #: ../restaurant-reservations.php:279
50
- msgid "Help"
 
 
51
  msgstr ""
 
 
 
52
 
53
- #: ../includes/Booking.class.php:154
54
- msgid "Please enter the date you would like to book."
55
- msgstr ""
56
 
57
- #: ../includes/Booking.class.php:164
58
  msgid ""
59
- "The date you entered is not valid. Please select from one of the dates in "
60
- "the calendar."
61
  msgstr ""
 
 
 
62
 
63
- #: ../includes/Booking.class.php:175
64
- msgid "Please enter the time you would like to book."
65
- msgstr ""
66
 
67
- #: ../includes/Booking.class.php:185
68
  msgid ""
69
- "The time you entered is not valid. Please select from one of the times "
70
- "provided."
71
  msgstr ""
 
 
72
 
73
- #: ../includes/Booking.class.php:204
74
- #, php-format
75
- msgid "Sorry, bookings can not be made more than %s days in advance."
76
- msgstr ""
77
 
78
- #: ../includes/Booking.class.php:215
79
- msgid "Sorry, bookings can not be made in the past."
80
- msgstr ""
81
 
82
- #: ../includes/Booking.class.php:223
83
- #, php-format
84
- msgid "Sorry, bookings must be made more than %s days in advance."
85
- msgstr ""
86
 
87
- #: ../includes/Booking.class.php:225
88
- #, php-format
89
- msgid "Sorry, bookings must be made more than %s hours in advance."
90
- msgstr ""
91
 
92
- #: ../includes/Booking.class.php:227
93
- #, php-format
94
- msgid "Sorry, bookings must be made more than %s mings in advance."
95
- msgstr ""
96
 
97
- #: ../includes/Booking.class.php:266
98
- msgid "Sorry, no bookings are being accepted then."
99
- msgstr ""
 
100
 
101
- #: ../includes/Booking.class.php:318
102
- msgid "Sorry, no bookings are being accepted on that date."
103
- msgstr ""
 
104
 
105
- #: ../includes/Booking.class.php:324
106
- msgid "Sorry, no bookings are being accepted at that time."
107
- msgstr ""
 
108
 
109
- #: ../includes/Booking.class.php:346
110
- msgid "Please enter a name for this booking."
111
- msgstr ""
 
112
 
113
- #: ../includes/Booking.class.php:356
114
- msgid "Please let us know how many people will be in your party."
115
- msgstr ""
 
116
 
117
- #: ../includes/Booking.class.php:370
118
- #, php-format
119
- msgid "We only accept bookings for parties of up to %d people."
120
- msgstr ""
121
 
122
- #: ../includes/Booking.class.php:381
123
- msgid "Please enter an email address so we can confirm your booking."
 
 
124
  msgstr ""
 
 
125
 
126
- #: ../includes/CustomPostTypes.class.php:38 ../includes/CustomPostTypes.class.php:
127
- #: 40 ../includes/CustomPostTypes.class.php:41 ../includes/WP_List_Table.
128
- #: BookingsTable.class.php:76
129
- msgid "Bookings"
130
- msgstr ""
131
 
132
- #: ../includes/CustomPostTypes.class.php:39 ../includes/WP_List_Table.
133
- #: BookingsTable.class.php:75
134
- msgid "Booking"
135
- msgstr ""
136
 
137
- #: ../includes/CustomPostTypes.class.php:42
138
- msgid "Add New"
139
- msgstr ""
140
 
141
- #: ../includes/CustomPostTypes.class.php:43
142
- msgid "Add New Booking"
143
- msgstr ""
144
 
145
- #: ../includes/CustomPostTypes.class.php:44
146
- msgid "Edit Booking"
147
- msgstr ""
148
 
149
- #: ../includes/CustomPostTypes.class.php:45
150
- msgid "New Booking"
151
- msgstr ""
152
 
153
- #: ../includes/CustomPostTypes.class.php:46
154
- msgid "View Booking"
155
- msgstr ""
156
 
157
- #: ../includes/CustomPostTypes.class.php:47
158
- msgid "Search Bookings"
159
- msgstr ""
160
 
161
- #: ../includes/CustomPostTypes.class.php:48
162
- msgid "No bookings found"
163
- msgstr ""
164
 
165
- #: ../includes/CustomPostTypes.class.php:49
166
- msgid "No bookings found in trash"
167
- msgstr ""
168
 
169
- #: ../includes/CustomPostTypes.class.php:50
170
- msgid "All Bookings"
171
- msgstr ""
172
 
173
- #: ../includes/CustomPostTypes.class.php:80
174
- msgctxt "Booking status when it is pending review"
175
- msgid "Pending"
176
- msgstr ""
177
 
178
- #: ../includes/CustomPostTypes.class.php:86
179
- msgctxt "Booking status for a confirmed booking"
180
- msgid "Confirmed"
181
- msgstr ""
182
 
183
- #: ../includes/CustomPostTypes.class.php:93
184
- #, php-format
185
- msgid "Confirmed <span class=\"count\">(%s)</span>"
186
- msgid_plural "Confirmed <span class=\"count\">(%s)</span>"
187
- msgstr[0] ""
188
- msgstr[1] ""
189
 
190
- #: ../includes/CustomPostTypes.class.php:97
191
- msgctxt "Booking status for a closed booking"
192
- msgid "Closed"
193
- msgstr ""
194
 
195
- #: ../includes/CustomPostTypes.class.php:104
196
- #, php-format
197
- msgid "Closed <span class=\"count\">(%s)</span>"
198
- msgid_plural "Closed <span class=\"count\">(%s)</span>"
199
- msgstr[0] ""
200
- msgstr[1] ""
201
 
202
- #: ../includes/Notification.class.php:87
203
- msgid "View pending bookings"
204
- msgstr ""
205
 
206
- #: ../includes/Notification.class.php:88
207
- msgid "Confirm this booking"
208
- msgstr ""
209
 
210
- #: ../includes/Notification.class.php:89
211
- msgid "Reject this booking"
212
- msgstr ""
213
 
214
- #: ../includes/Settings.class.php:83
215
  msgid ""
216
- "Thanks, your booking request is waiting to be confirmed. Updates will be "
217
- "sent to the email address you provided."
218
  msgstr ""
 
 
219
 
220
- #: ../includes/Settings.class.php:84
221
- msgctxt ""
222
- "Default date format for display. Must match formatting rules at http://amsul."
223
- "ca/pickadate.js/date.htm#formatting-rules"
224
- msgid "mmmm d, yyyy"
225
- msgstr ""
226
 
227
- #: ../includes/Settings.class.php:85
228
- msgctxt ""
229
- "Default time format for display. Must match formatting rules at http://amsul."
230
- "ca/pickadate.js/time.htm#formats"
231
- msgid "h:i A"
232
- msgstr ""
233
 
234
- #: ../includes/Settings.class.php:86
235
- msgctxt "Default interval in minutes when selecting a time."
236
- msgid "30"
237
- msgstr ""
238
 
239
- #: ../includes/Settings.class.php:96
240
- msgctxt "Default email subject for admin notifications of new bookings"
241
- msgid "New Booking Request"
242
- msgstr ""
243
 
244
- #: ../includes/Settings.class.php:97
245
- msgctxt ""
246
- "Default email sent to the admin when a new booking request is made. The tags "
247
- "in {brackets} will be replaced by the appropriate content and should be left "
248
- "in place. HTML is allowed, but be aware that many email clients do not "
249
- "handle HTML very well."
250
- msgid ""
251
- "A new booking request has been made at {site_name}:\n"
252
- "\n"
253
- "{user_name}\n"
254
- "{party} people\n"
255
- "{date}\n"
256
- "\n"
257
- "{bookings_link}\n"
258
- "{confirm_link}\n"
259
- "{close_link}\n"
260
- "\n"
261
- "&nbsp;\n"
262
- "\n"
263
- "<em>This message was sent by {site_link} on {current_time}.</em>"
264
- msgstr ""
265
 
266
- #: ../includes/Settings.class.php:115
267
- #, php-format
268
- msgctxt ""
269
- "Default email subject sent to user when they request a booking. %s will be "
270
- "replaced by the website name"
271
- msgid "Your booking at %s is pending"
272
- msgstr ""
273
 
274
- #: ../includes/Settings.class.php:116
275
- msgctxt ""
276
- "Default email sent to users when they make a new booking request. The tags "
277
- "in {brackets} will be replaced by the appropriate content and should be left "
278
- "in place. HTML is allowed, but be aware that many email clients do not "
279
- "handle HTML very well."
280
- msgid ""
281
- "Thanks {user_name},\n"
282
- "\n"
283
- "Your booking request is <strong>waiting to be confirmed</strong>.\n"
284
- "\n"
285
- "Give us a few moments to make sure that we've got space for you. You will "
286
- "receive another email from us soon. If this request was made outside of our "
287
- "normal working hours, we may not be able to confirm it until we're open "
288
- "again.\n"
289
- "\n"
290
- "<strong>Your request details:</strong>\n"
291
- "{user_name}\n"
292
- "{party} people\n"
293
- "{date}\n"
294
- "\n"
295
- "&nbsp;\n"
296
- "\n"
297
- "<em>This message was sent by {site_link} on {current_time}.</em>"
298
- msgstr ""
299
 
300
- #: ../includes/Settings.class.php:135
301
- #, php-format
302
- msgctxt ""
303
- "Default email subject sent to user when their booking is confirmed. %s will "
304
- "be replaced by the website name"
305
- msgid "Your booking at %s is confirmed"
306
- msgstr ""
307
 
308
- #: ../includes/Settings.class.php:136
309
- msgctxt ""
310
- "Default email sent to users when they make a new booking request. The tags "
311
- "in {brackets} will be replaced by the appropriate content and should be left "
312
- "in place. HTML is allowed, but be aware that many email clients do not "
313
- "handle HTML very well."
314
- msgid ""
315
- "Hi {user_name},\n"
316
- "\n"
317
- "Your booking request has been <strong>confirmed</strong>. We look forward to "
318
- "seeing you soon.\n"
319
- "\n"
320
- "<strong>Your booking:</strong>\n"
321
- "{user_name}\n"
322
- "{party} people\n"
323
- "{date}\n"
324
- "\n"
325
- "&nbsp;\n"
326
- "\n"
327
- "<em>This message was sent by {site_link} on {current_time}.</em>"
328
- msgstr ""
329
 
330
- #: ../includes/Settings.class.php:153
331
- #, php-format
332
- msgctxt ""
333
- "Default email subject sent to user when their booking is rejected. %s will "
334
- "be replaced by the website name"
335
- msgid "Your booking at %s was not accepted"
336
- msgstr ""
337
 
338
- #: ../includes/Settings.class.php:154
339
- msgctxt ""
340
- "Default email sent to users when they make a new booking request. The tags "
341
- "in {brackets} will be replaced by the appropriate content and should be left "
342
- "in place. HTML is allowed, but be aware that many email clients do not "
343
- "handle HTML very well."
344
- msgid ""
345
- "Hi {user_name},\n"
346
- "\n"
347
- "Sorry, we could not accomodate your booking request. We're full or not open "
348
- "at the time you requested:\n"
349
- "\n"
350
- "{user_name}\n"
351
- "{party} people\n"
352
- "{date}\n"
353
- "\n"
354
- "&nbsp;\n"
355
- "\n"
356
- "<em>This message was sent by {site_link} on {current_time}.</em>"
357
- msgstr ""
358
 
359
- #: ../includes/Settings.class.php:218 ../includes/Settings.class.php:219
360
- msgid "Settings"
361
- msgstr ""
362
 
363
- #: ../includes/Settings.class.php:231
364
- msgid "General"
 
 
365
  msgstr ""
 
 
366
 
367
- #: ../includes/Settings.class.php:242
368
- msgid "Booking Page"
369
- msgstr ""
370
 
371
- #: ../includes/Settings.class.php:243
372
  msgid ""
373
- "Select a page on your site to automatically display the booking form and "
374
- "confirmation message."
375
  msgstr ""
 
 
376
 
377
- #: ../includes/Settings.class.php:259
378
- msgid "Max Party Size"
379
- msgstr ""
380
 
381
- #: ../includes/Settings.class.php:260
 
 
 
 
 
 
 
 
 
 
 
 
382
  msgid ""
383
- "Set a maximum allowed party size for bookings. Leave it empty to allow "
384
- "parties of any size."
385
  msgstr ""
 
 
386
 
387
- #: ../includes/Settings.class.php:261
388
- msgid "No limit"
389
- msgstr ""
390
 
391
- #: ../includes/Settings.class.php:271
392
- msgid "Success Message"
393
- msgstr ""
394
 
395
- #: ../includes/Settings.class.php:272
396
- msgid "Enter the message to display when a booking request is made."
397
- msgstr ""
398
 
399
- #: ../includes/Settings.class.php:283
400
- msgid "Date Format"
401
- msgstr ""
402
 
403
- #: ../includes/Settings.class.php:284
404
- msgid ""
405
- "Define how the date should appear after it has been selected. <a href=\"http:"
406
- "//amsul.ca/pickadate.js/date.htm#formatting-rules\">Formatting rules</a>"
407
- msgstr ""
408
 
409
- #: ../includes/Settings.class.php:295
410
- msgid "Time Format"
411
- msgstr ""
412
 
413
- #: ../includes/Settings.class.php:296
414
- msgid ""
415
- "Define how the time should appear after it has been selected. <a href=\"http:"
416
- "//amsul.ca/pickadate.js/time.htm#formatting-rules\">Formatting rules</a>"
417
- msgstr ""
418
 
419
- #: ../includes/Settings.class.php:309
420
- msgid "Language"
421
- msgstr ""
422
 
423
- #: ../includes/Settings.class.php:310
424
- msgid ""
425
- "Select a language to use for the booking form datepicker if it is different "
426
- "than your WordPress language setting."
427
- msgstr ""
428
 
429
- #: ../includes/Settings.class.php:320
430
- msgid "Booking Schedule"
431
- msgstr ""
432
 
433
- #: ../includes/Settings.class.php:331
434
- msgid "Schedule"
435
- msgstr ""
436
 
437
- #: ../includes/Settings.class.php:332
438
- msgid "Define the weekly schedule during which you accept bookings."
439
- msgstr ""
440
 
441
- #: ../includes/Settings.class.php:334
442
- msgctxt "Monday abbreviation"
443
- msgid "Mo"
444
- msgstr ""
445
 
446
- #: ../includes/Settings.class.php:335
447
- msgctxt "Tuesday abbreviation"
448
- msgid "Tu"
449
- msgstr ""
450
 
451
- #: ../includes/Settings.class.php:336
452
- msgctxt "Wednesday abbreviation"
453
- msgid "We"
 
454
  msgstr ""
 
 
455
 
456
- #: ../includes/Settings.class.php:337
457
- msgctxt "Thursday abbreviation"
458
- msgid "Th"
459
- msgstr ""
460
 
461
- #: ../includes/Settings.class.php:338
462
- msgctxt "Friday abbreviation"
463
- msgid "Fr"
 
464
  msgstr ""
 
 
465
 
466
- #: ../includes/Settings.class.php:339
467
- msgctxt "Saturday abbreviation"
468
- msgid "Sa"
469
- msgstr ""
470
 
471
- #: ../includes/Settings.class.php:340
472
- msgctxt "Sunday abbreviation"
473
- msgid "Su"
 
474
  msgstr ""
475
 
476
- #: ../includes/Settings.class.php:355
477
- msgid "Exceptions"
478
  msgstr ""
479
 
480
- #: ../includes/Settings.class.php:356
481
  msgid ""
482
- "Define special opening hours for holidays, events or other needs. Leave the "
483
- "time empty if you're closed all day."
484
  msgstr ""
485
 
486
- #: ../includes/Settings.class.php:362
487
- msgctxt "Brief description of a scheduling exception when no times are set"
488
- msgid "Closed all day"
489
  msgstr ""
490
 
491
- #: ../includes/Settings.class.php:373
492
- msgid "Early Bookings"
493
  msgstr ""
494
 
495
- #: ../includes/Settings.class.php:374
496
- msgid "Select how early customers can make their booking."
497
  msgstr ""
498
 
499
- #: ../includes/Settings.class.php:377
500
- msgid "Any time"
501
  msgstr ""
502
 
503
- #: ../includes/Settings.class.php:378
504
- msgid "Up to 1 day in advance"
505
  msgstr ""
506
 
507
- #: ../includes/Settings.class.php:379
508
- msgid "Up to 1 week in advance"
509
  msgstr ""
510
 
511
- #: ../includes/Settings.class.php:380
512
- msgid "Up to 2 weeks in advance"
513
- msgstr ""
514
 
515
- #: ../includes/Settings.class.php:381
516
- msgid "Up to 30 days in advance"
517
- msgstr ""
 
518
 
519
- #: ../includes/Settings.class.php:382
520
- msgid "Up to 90 days in advance"
521
- msgstr ""
 
522
 
523
- #: ../includes/Settings.class.php:393
524
- msgid "Late Bookings"
525
- msgstr ""
 
 
 
 
526
 
527
- #: ../includes/Settings.class.php:394
528
- msgid "Select how late customers can make their booking."
529
- msgstr ""
530
 
531
- #: ../includes/Settings.class.php:397
532
- msgid "Up to the last minute"
533
- msgstr ""
534
 
535
- #: ../includes/Settings.class.php:398
536
- msgid "At least 15 minutes in advance"
537
- msgstr ""
 
 
538
 
539
- #: ../includes/Settings.class.php:399
540
- msgid "At least 30 minutes in advance"
541
- msgstr ""
542
 
543
- #: ../includes/Settings.class.php:400
544
- msgid "At least 45 minutes in advance"
545
- msgstr ""
 
 
546
 
547
- #: ../includes/Settings.class.php:401
548
- msgid "At least 1 hour in advance"
549
- msgstr ""
 
550
 
551
- #: ../includes/Settings.class.php:402
552
- msgid "At least 4 hours in advance"
553
- msgstr ""
554
 
555
- #: ../includes/Settings.class.php:403
556
- msgid "At least 1 day in advance"
557
- msgstr ""
 
558
 
559
- #: ../includes/Settings.class.php:414
560
- msgid "Date Pre-selection"
561
- msgstr ""
 
562
 
563
- #: ../includes/Settings.class.php:415
564
- msgid ""
565
- "When the booking form is loaded, should it automatically attempt to select a "
566
- "valid date?"
567
- msgstr ""
568
 
569
- #: ../includes/Settings.class.php:418
570
- msgid "Select today or soonest valid date"
571
- msgstr ""
572
 
573
- #: ../includes/Settings.class.php:419
574
- msgid "Leave empty"
575
- msgstr ""
576
 
577
- #: ../includes/Settings.class.php:430
578
- msgid "Time Interval"
579
- msgstr ""
580
 
581
- #: ../includes/Settings.class.php:431
582
- msgid "Select the number of minutes between each available time."
583
- msgstr ""
584
 
585
- #: ../includes/Settings.class.php:434
586
- msgid "Every 30 minutes"
587
- msgstr ""
588
 
589
- #: ../includes/Settings.class.php:435
590
- msgid "Every 15 minutes"
591
- msgstr ""
 
592
 
593
- #: ../includes/Settings.class.php:436
594
- msgid "Every 10 minutes"
595
- msgstr ""
596
 
597
- #: ../includes/Settings.class.php:437
598
- msgid "Every 5 minutes"
599
- msgstr ""
 
 
600
 
601
- #: ../includes/Settings.class.php:446
602
- msgid "Notifications"
603
- msgstr ""
 
604
 
605
- #: ../includes/Settings.class.php:457
606
- msgid "Reply-To Name"
607
- msgstr ""
608
 
609
- #: ../includes/Settings.class.php:458
610
- msgid "The name which should appear in the Reply-To field of a notification email"
611
- msgstr ""
612
 
613
- #: ../includes/Settings.class.php:469
614
- msgid "Reply-To Email Address"
615
- msgstr ""
616
 
617
- #: ../includes/Settings.class.php:470
618
- msgid ""
619
- "The email address which should appear in the Reply-To field of a "
620
- "notification email."
621
- msgstr ""
622
 
623
- #: ../includes/Settings.class.php:481
624
- msgid "Admin Notification"
625
- msgstr ""
626
 
627
- #: ../includes/Settings.class.php:482
628
- msgid ""
629
- "Send an email notification to an administrator when a new booking is "
630
- "requested."
631
- msgstr ""
632
 
633
- #: ../includes/Settings.class.php:492
634
- msgid "Admin Email Address"
635
- msgstr ""
636
 
637
- #: ../includes/Settings.class.php:493
638
- msgid "The email address where admin notifications should be sent."
639
- msgstr ""
640
 
641
- #: ../includes/Settings.class.php:502
642
- msgid "Email Templates"
643
- msgstr ""
644
 
645
- #: ../includes/Settings.class.php:516
646
- msgid "Template Tags"
647
- msgstr ""
 
648
 
649
- #: ../includes/Settings.class.php:518
650
- msgid ""
651
- "Use the following tags to automatically add booking information to the "
652
- "emails."
653
- msgstr ""
654
 
655
- #: ../includes/Settings.class.php:520
656
- msgid "Name of the user who made the booking"
657
- msgstr ""
 
 
 
 
 
 
 
658
 
659
- #: ../includes/Settings.class.php:523
660
- msgid "Number of people booked"
661
- msgstr ""
 
662
 
663
- #: ../includes/Settings.class.php:526
664
- msgid "Date and time of the booking"
665
- msgstr ""
 
 
 
 
 
 
 
666
 
667
- #: ../includes/Settings.class.php:529
668
- msgid "Phone number if supplied with the request"
669
- msgstr ""
670
 
671
- #: ../includes/Settings.class.php:532
672
- msgid "Message added to the request"
673
- msgstr ""
674
 
675
- #: ../includes/Settings.class.php:535
676
- msgid "A link to the admin panel showing pending bookings"
677
- msgstr ""
678
 
679
- #: ../includes/Settings.class.php:538
680
- msgid "A link to confirm this booking. Only include this in admin notifications"
 
 
681
  msgstr ""
 
 
682
 
683
- #: ../includes/Settings.class.php:541
684
- msgid "A link to reject this booking. Only include this in admin notifications"
 
 
 
685
  msgstr ""
 
 
686
 
687
- #: ../includes/Settings.class.php:544
688
- msgid "The name of this website"
689
- msgstr ""
 
 
 
690
 
691
- #: ../includes/Settings.class.php:547
692
- msgid "A link to this website"
693
- msgstr ""
 
694
 
695
- #: ../includes/Settings.class.php:550
696
- msgid "Current date and time"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
697
  msgstr ""
 
 
 
 
 
 
 
 
 
 
 
698
 
699
- #: ../includes/Settings.class.php:561
700
- msgid "Admin Notification Subject"
701
- msgstr ""
 
 
 
 
702
 
703
- #: ../includes/Settings.class.php:562
704
- msgid "The email subject for admin notifications."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
705
  msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
706
 
707
- #: ../includes/Settings.class.php:573
708
- msgid "Admin Notification Email"
709
- msgstr ""
 
 
 
 
710
 
711
- #: ../includes/Settings.class.php:574
 
 
 
 
 
712
  msgid ""
713
- "Enter the email an admin should receive when an initial booking request is "
714
- "made."
 
 
 
 
 
 
 
 
 
 
 
715
  msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
716
 
717
- #: ../includes/Settings.class.php:585
718
- msgid "New Request Email Subject"
719
- msgstr ""
 
 
 
 
720
 
721
- #: ../includes/Settings.class.php:586
 
 
 
 
 
722
  msgid ""
723
- "The email subject a user should receive when they make an initial booking "
724
- "request."
 
 
 
 
 
 
 
 
 
 
725
  msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
726
 
727
- #: ../includes/Settings.class.php:597
728
- msgid "New Request Email"
729
- msgstr ""
730
 
731
- #: ../includes/Settings.class.php:598
732
- msgid ""
733
- "Enter the email a user should receive when they make an initial booking "
734
- "request."
735
- msgstr ""
736
 
737
- #: ../includes/Settings.class.php:609
738
- msgid "Confirmed Email Subject"
739
- msgstr ""
740
 
741
- #: ../includes/Settings.class.php:610
742
  msgid ""
743
- "The email subject a user should receive when their booking has been "
744
- "confirmed."
745
- msgstr ""
746
-
747
- #: ../includes/Settings.class.php:621
748
- msgid "Confirmed Email"
749
  msgstr ""
 
 
750
 
751
- #: ../includes/Settings.class.php:622
752
- msgid "Enter the email a user should receive when their booking has been confirmed."
753
- msgstr ""
754
 
755
- #: ../includes/Settings.class.php:633
756
- msgid "Rejected Email Subject"
 
 
757
  msgstr ""
 
 
758
 
759
- #: ../includes/Settings.class.php:634
760
- msgid "The email subject a user should receive when their booking has been rejected."
761
- msgstr ""
762
 
763
- #: ../includes/Settings.class.php:645
764
- msgid "Rejected Email"
765
- msgstr ""
766
 
767
- #: ../includes/Settings.class.php:646
768
- msgid "Enter the email a user should receive when their booking has been rejected."
769
  msgstr ""
 
 
770
 
771
  #: ../includes/template-functions.php:84
772
  msgid "Book a table"
773
- msgstr ""
774
 
775
  #: ../includes/template-functions.php:89 ../includes/WP_List_Table.BookingsTable.
776
  #: class.php:267 ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.
777
  #: class.php:365
778
  msgid "Date"
779
- msgstr ""
780
 
781
  #: ../includes/template-functions.php:96
782
  msgid "Time"
783
- msgstr ""
784
 
785
  #: ../includes/template-functions.php:103 ../includes/WP_List_Table.BookingsTable.
786
  #: class.php:268
787
  msgid "Party"
788
- msgstr ""
789
 
790
  #: ../includes/template-functions.php:110
791
  msgid "Contact Details"
792
- msgstr ""
793
 
794
  #: ../includes/template-functions.php:115 ../includes/WP_List_Table.BookingsTable.
795
  #: class.php:269
796
  msgid "Name"
797
- msgstr ""
798
 
799
  #: ../includes/template-functions.php:122 ../includes/WP_List_Table.BookingsTable.
800
  #: class.php:270
801
  msgid "Email"
802
- msgstr ""
803
 
804
  #: ../includes/template-functions.php:129 ../includes/WP_List_Table.BookingsTable.
805
  #: class.php:271
806
  msgid "Phone"
807
- msgstr ""
808
 
809
  #: ../includes/template-functions.php:135
810
  msgid "Add a Message"
811
- msgstr ""
812
 
813
  #: ../includes/template-functions.php:141 ../includes/WP_List_Table.BookingsTable.
814
  #: class.php:272
815
  msgid "Message"
816
- msgstr ""
817
 
818
  #: ../includes/template-functions.php:146
819
  msgid "Request Booking"
820
- msgstr ""
821
 
822
  #: ../includes/WP_List_Table.BookingsTable.class.php:172 ..
823
- #: /includes/WP_List_Table.BookingsTable.class.php:235
824
  msgid "All"
825
- msgstr ""
826
 
827
  #: ../includes/WP_List_Table.BookingsTable.class.php:173
828
  msgid "Today"
829
- msgstr ""
830
 
831
  #: ../includes/WP_List_Table.BookingsTable.class.php:174
832
  msgid "Upcoming"
833
- msgstr ""
834
 
835
  #: ../includes/WP_List_Table.BookingsTable.class.php:180
836
  msgctxt "Separator between two dates in a date range"
837
  msgid "&mdash;"
838
- msgstr ""
839
 
840
  #: ../includes/WP_List_Table.BookingsTable.class.php:192
841
  msgid "Start Date:"
842
- msgstr ""
843
 
844
  #: ../includes/WP_List_Table.BookingsTable.class.php:193
845
  msgid "Start Date"
846
- msgstr ""
847
 
848
  #: ../includes/WP_List_Table.BookingsTable.class.php:194
849
  msgid "End Date:"
850
- msgstr ""
851
 
852
  #: ../includes/WP_List_Table.BookingsTable.class.php:195
853
  msgid "End Date"
854
- msgstr ""
855
 
856
  #: ../includes/WP_List_Table.BookingsTable.class.php:196
857
  msgid "Apply"
858
- msgstr ""
859
 
860
  #: ../includes/WP_List_Table.BookingsTable.class.php:198
861
  msgid "Clear Filter"
862
- msgstr ""
863
 
864
  #: ../includes/WP_List_Table.BookingsTable.class.php:236
865
  msgid "Pending"
866
- msgstr ""
867
 
868
  #: ../includes/WP_List_Table.BookingsTable.class.php:237
869
  msgid "Confirmed"
870
- msgstr ""
871
 
872
  #: ../includes/WP_List_Table.BookingsTable.class.php:238
873
  msgid "Closed"
874
- msgstr ""
875
 
876
  #: ../includes/WP_List_Table.BookingsTable.class.php:239
877
  msgid "Trash"
878
- msgstr ""
879
 
880
  #: ../includes/WP_List_Table.BookingsTable.class.php:273
881
  msgid "Status"
882
- msgstr ""
883
 
884
  #: ../includes/WP_List_Table.BookingsTable.class.php:324
885
  msgctxt "Status label for bookings put in the trash"
886
  msgid "Trash"
887
- msgstr ""
888
 
889
  #: ../includes/WP_List_Table.BookingsTable.class.php:356
890
  msgid "Delete"
891
- msgstr ""
892
 
893
  #: ../includes/WP_List_Table.BookingsTable.class.php:357
894
  msgid "Set To Confirmed"
895
- msgstr ""
896
 
897
  #: ../includes/WP_List_Table.BookingsTable.class.php:358
898
  msgid "Set To Pending Review"
899
- msgstr ""
900
 
901
  #: ../includes/WP_List_Table.BookingsTable.class.php:359
902
  msgid "Set To Closed"
903
- msgstr ""
904
 
905
  #: ../includes/WP_List_Table.BookingsTable.class.php:471
906
  #, php-format
907
  msgid "%d booking deleted successfully."
908
  msgid_plural "%d bookings deleted successfully."
909
- msgstr[0] ""
910
- msgstr[1] ""
911
 
912
  #: ../includes/WP_List_Table.BookingsTable.class.php:474
913
  #, php-format
914
  msgid "%d booking confirmed."
915
  msgid_plural "%d bookings confirmed."
916
- msgstr[0] ""
917
- msgstr[1] ""
918
 
919
  #: ../includes/WP_List_Table.BookingsTable.class.php:477
920
  #, php-format
921
  msgid "%d booking set to pending."
922
  msgid_plural "%d bookings set to pending."
923
- msgstr[0] ""
924
- msgstr[1] ""
925
 
926
  #: ../includes/WP_List_Table.BookingsTable.class.php:480
927
  #, php-format
928
  msgid "%d booking closed."
929
  msgid_plural "%d bookings closed."
930
- msgstr[0] ""
931
- msgstr[1] ""
932
 
933
  #: ../includes/WP_List_Table.BookingsTable.class.php:492
934
  #, php-format
935
  msgid "%d booking had errors and could not be processed."
936
  msgid_plural "%d bookings had errors and could not be processed."
937
- msgstr[0] ""
938
- msgstr[1] ""
939
 
940
  #: ../includes/WP_Widget.BookingFormWidget.class.php:25
941
  msgid "Booking Form"
942
- msgstr ""
943
 
944
  #: ../includes/WP_Widget.BookingFormWidget.class.php:26
945
  msgid "Display a form to accept bookings."
946
- msgstr ""
947
 
948
  #: ../includes/WP_Widget.BookingFormWidget.class.php:64
949
  msgid "Title"
950
- msgstr ""
951
 
952
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:266
953
  msgid "Add new scheduling rule"
954
- msgstr ""
955
 
956
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:293 ..
957
- #: /lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:306
958
  msgctxt "Format of a scheduling rule"
959
  msgid "Weekly"
960
- msgstr ""
961
 
962
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:295 ..
963
- #: /lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:314
964
  msgctxt "Format of a scheduling rule"
965
  msgid "Monthly"
966
- msgstr ""
967
 
968
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:297 ..
969
- #: /lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:322
970
  msgctxt "Format of a scheduling rule"
971
  msgid "Date"
972
- msgstr ""
973
 
974
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:333
975
  msgctxt "Label for selecting days of the week in a scheduling rule"
976
  msgid "Days of the week"
977
- msgstr ""
978
 
979
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:349
980
  msgctxt "Label for selecting weeks of the month in a scheduling rule"
981
  msgid "Weeks of the month"
982
- msgstr ""
983
 
984
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:380
985
  msgctxt "Label to select time slot for a scheduling rule"
986
  msgid "Time"
987
- msgstr ""
988
 
989
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:385
990
  msgctxt "Label to set a scheduling rule to last all day"
991
  msgid "All day"
992
- msgstr ""
993
 
994
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:394
995
  msgctxt "Label for the starting time of a scheduling rule"
996
  msgid "Start"
997
- msgstr ""
998
 
999
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:402
1000
  msgctxt "Label for the ending time of a scheduling rule"
1001
  msgid "End"
1002
- msgstr ""
1003
 
1004
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:411
1005
  msgctxt "Prompt displayed when a scheduling rule is set without any time restrictions."
@@ -1007,33 +1109,35 @@ msgid ""
1007
  "All day long. Want to <a href=\"#\" data-format=\"time-slot\">set a time "
1008
  "slot</a>?"
1009
  msgstr ""
 
 
1010
 
1011
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:430 ..
1012
- #: /lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:433
1013
  msgid "Open and close this rule"
1014
- msgstr ""
1015
 
1016
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:436
1017
  msgid "Delete rule"
1018
- msgstr ""
1019
 
1020
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:439
1021
  msgid "Delete scheduling rule"
1022
- msgstr ""
1023
 
1024
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:523
1025
  msgctxt ""
1026
  "Brief default description of a scheduling rule when no weekdays or weeks are "
1027
  "included in the rule."
1028
  msgid "Never"
1029
- msgstr ""
1030
 
1031
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:524
1032
  msgctxt ""
1033
  "Brief default description of a scheduling rule when all the weekdays/weeks "
1034
  "are included in the rule."
1035
  msgid "Every day"
1036
- msgstr ""
1037
 
1038
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:525
1039
  msgctxt ""
@@ -1043,7 +1147,7 @@ msgctxt ""
1043
  "first one) and weeks (the second one) in the following format: M, T, W on "
1044
  "the first, second week of the month"
1045
  msgid "{days} on the {weeks} week of the month"
1046
- msgstr ""
1047
 
1048
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:526
1049
  msgctxt ""
@@ -1052,28 +1156,28 @@ msgctxt ""
1052
  "and will be replaced by a comma-separated list of weeks (the second one) in "
1053
  "the following format: First, second week of the month"
1054
  msgid "{weeks} week of the month"
1055
- msgstr ""
1056
 
1057
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:527
1058
  msgctxt "Brief default description of a scheduling rule when no times are set"
1059
  msgid "All day"
1060
- msgstr ""
1061
 
1062
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:528
1063
  msgctxt ""
1064
  "Brief default description of a scheduling rule when an end time is set but "
1065
  "no start time. If the end time is 6pm, it will read: Ends at 6pm."
1066
  msgid "Ends at"
1067
- msgstr ""
1068
 
1069
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:529
1070
  msgctxt ""
1071
  "Brief default description of a scheduling rule when a start time is set but "
1072
  "no end time. If the start time is 6pm, it will read: Starts at 6pm."
1073
  msgid "Starts at"
1074
- msgstr ""
1075
 
1076
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:530
1077
  msgctxt "Default separator between times of a scheduling rule."
1078
  msgid "&mdash;"
1079
- msgstr ""
 
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: Restaurant Reservations\n"
4
  "Report-Msgid-Bugs-To: \n"
5
  "POT-Creation-Date: Thu Jul 17 2014 15:43:57 GMT+0100 (GMT Daylight Time)\n"
6
+ "PO-Revision-Date: Fri Jan 16 2015 08:51:34 GMT+0100 (West-Europa "
7
+ "(standaardtijd))\n"
8
+ "Last-Translator: Dick <massimo@studio020.com>\n"
9
  "Language-Team: \n"
10
+ "Language: Dutch\n"
11
+ "Plural-Forms: nplurals=2; plural=n != 1\n"
12
  "MIME-Version: 1.0\n"
13
  "Content-Type: text/plain; charset=UTF-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
20
  "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
21
  "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
22
  "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
23
+ "X-Generator: Loco - https://localise.biz/\n"
24
+ "X-Loco-Target-Locale: nl_NL"
25
 
26
+ #: ../includes/Settings.class.php:283
27
+ msgid "Date Format"
28
+ msgstr "Datum notatie"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ #: ../includes/Settings.class.php:284
31
+ msgid ""
32
+ "Define how the date should appear after it has been selected. <a href=\"http:"
33
+ "//amsul.ca/pickadate.js/date.htm#formatting-rules\">Formatting rules</a>"
34
  msgstr ""
35
+ "Bepaal hoe de datum moet worden weergegeven nadat deze is geselecteerd. <a "
36
+ "href=\"http://amsul.ca/pickadate.js/date.htm#formatting-"
37
+ "rules\">formatteringsregels</a>"
38
 
39
+ #: ../includes/Settings.class.php:295
40
+ msgid "Time Format"
41
+ msgstr "Tijdsaanduiding"
42
 
43
+ #: ../includes/Settings.class.php:296
44
  msgid ""
45
+ "Define how the time should appear after it has been selected. <a href=\"http:"
46
+ "//amsul.ca/pickadate.js/time.htm#formatting-rules\">Formatting rules</a>"
47
  msgstr ""
48
+ "Bepaal hoe de tijd moet worden weergegeven nadat deze is geselecteerd. <a "
49
+ "href=\"http://amsul.ca/pickadate.js/time.htm#formatting-"
50
+ "rules\">formatteringsregels</a>"
51
 
52
+ #: ../includes/Settings.class.php:309
53
+ msgid "Language"
54
+ msgstr "Taal"
55
 
56
+ #: ../includes/Settings.class.php:310
57
  msgid ""
58
+ "Select a language to use for the booking form datepicker if it is different "
59
+ "than your WordPress language setting."
60
  msgstr ""
61
+ "Selecteer een taal om te gebruiken voor het boekingsformulier datepicker als "
62
+ "het is anders dan je WordPress taalinstelling."
63
 
64
+ #: ../includes/Settings.class.php:320
65
+ msgid "Booking Schedule"
66
+ msgstr "Reserveringsschema"
 
67
 
68
+ #: ../includes/Settings.class.php:331
69
+ msgid "Schedule"
70
+ msgstr "Schema"
71
 
72
+ #: ../includes/Settings.class.php:332
73
+ msgid "Define the weekly schedule during which you accept bookings."
74
+ msgstr "Bepaal het wekelijkse schema waarin je reserveringen accepteerd."
 
75
 
76
+ #: ../includes/Settings.class.php:334
77
+ msgctxt "Monday abbreviation"
78
+ msgid "Mo"
79
+ msgstr "Ma"
80
 
81
+ #: ../includes/Settings.class.php:335
82
+ msgctxt "Tuesday abbreviation"
83
+ msgid "Tu"
84
+ msgstr "Di"
85
 
86
+ #: ../includes/Settings.class.php:336
87
+ msgctxt "Wednesday abbreviation"
88
+ msgid "We"
89
+ msgstr "Wo"
90
 
91
+ #: ../includes/Settings.class.php:337
92
+ msgctxt "Thursday abbreviation"
93
+ msgid "Th"
94
+ msgstr "Do"
95
 
96
+ #: ../includes/Settings.class.php:338
97
+ msgctxt "Friday abbreviation"
98
+ msgid "Fr"
99
+ msgstr "Vr"
100
 
101
+ #: ../includes/Settings.class.php:339
102
+ msgctxt "Saturday abbreviation"
103
+ msgid "Sa"
104
+ msgstr "Zat"
105
 
106
+ #: ../includes/Settings.class.php:340
107
+ msgctxt "Sunday abbreviation"
108
+ msgid "Su"
109
+ msgstr "Zon"
110
 
111
+ #: ../includes/Settings.class.php:355
112
+ msgid "Exceptions"
113
+ msgstr "Uitzonderingen"
 
114
 
115
+ #: ../includes/Settings.class.php:356
116
+ msgid ""
117
+ "Define special opening hours for holidays, events or other needs. Leave the "
118
+ "time empty if you're closed all day."
119
  msgstr ""
120
+ "Definieer speciale openingstijden voor de feestdagen, evenementen of andere "
121
+ "dagen. Laat de tijd leeg als je de hele dag gesloten zijn."
122
 
123
+ #: ../includes/Settings.class.php:362
124
+ msgctxt "Brief description of a scheduling exception when no times are set"
125
+ msgid "Closed all day"
126
+ msgstr "Gehele dag gesloten"
 
127
 
128
+ #: ../includes/Settings.class.php:373
129
+ msgid "Early Bookings"
130
+ msgstr "Vroege reserveringen"
 
131
 
132
+ #: ../includes/Settings.class.php:374
133
+ msgid "Select how early customers can make their booking."
134
+ msgstr "Selecteer hoe vroeg klanten kunnen hun boeking te maken."
135
 
136
+ #: ../includes/Settings.class.php:377
137
+ msgid "Any time"
138
+ msgstr "Altijd"
139
 
140
+ #: ../includes/Settings.class.php:378
141
+ msgid "Up to 1 day in advance"
142
+ msgstr "Tot 1 dag van tevoren"
143
 
144
+ #: ../includes/Settings.class.php:379
145
+ msgid "Up to 1 week in advance"
146
+ msgstr "Tot 1 week van tevoren"
147
 
148
+ #: ../includes/Settings.class.php:380
149
+ msgid "Up to 2 weeks in advance"
150
+ msgstr "Tot 1 weken van tevoren"
151
 
152
+ #: ../includes/Settings.class.php:381
153
+ msgid "Up to 30 days in advance"
154
+ msgstr "Tot 30 dagen van tevoren"
155
 
156
+ #: ../includes/Settings.class.php:382
157
+ msgid "Up to 90 days in advance"
158
+ msgstr "Tot 90 dagen van tevoren"
159
 
160
+ #: ../includes/Settings.class.php:393
161
+ msgid "Late Bookings"
162
+ msgstr "Late reserveringen"
163
 
164
+ #: ../includes/Settings.class.php:394
165
+ msgid "Select how late customers can make their booking."
166
+ msgstr "Selecteer op welke tijd klanten kunnen hun reserveringen kunnen doen."
167
 
168
+ #: ../includes/Settings.class.php:397
169
+ msgid "Up to the last minute"
170
+ msgstr "Tot op de laatste minuut"
 
171
 
172
+ #: ../includes/Settings.class.php:398
173
+ msgid "At least 15 minutes in advance"
174
+ msgstr "Ten minste 15 minuten vooraf"
 
175
 
176
+ #: ../includes/Settings.class.php:399
177
+ msgid "At least 30 minutes in advance"
178
+ msgstr "Ten minste 30 minuten vooraf"
 
 
 
179
 
180
+ #: ../includes/Settings.class.php:400
181
+ msgid "At least 45 minutes in advance"
182
+ msgstr "Ten minste 45 minuten vooraf"
 
183
 
184
+ #: ../includes/Settings.class.php:401
185
+ msgid "At least 1 hour in advance"
186
+ msgstr "Ten minste 1 uur vooraf"
 
 
 
187
 
188
+ #: ../includes/Settings.class.php:402
189
+ msgid "At least 4 hours in advance"
190
+ msgstr "Ten minste 4 uur vooraf"
191
 
192
+ #: ../includes/Settings.class.php:403
193
+ msgid "At least 1 day in advance"
194
+ msgstr "Ten minste 1 dag vooraf"
195
 
196
+ #: ../includes/Settings.class.php:414
197
+ msgid "Date Pre-selection"
198
+ msgstr "Datum voor-selectie"
199
 
200
+ #: ../includes/Settings.class.php:415
201
  msgid ""
202
+ "When the booking form is loaded, should it automatically attempt to select a "
203
+ "valid date?"
204
  msgstr ""
205
+ "Wanneer het reserveringssformulier is geladen, moet het automatisch proberen "
206
+ "om een geldige datum te selecteren?"
207
 
208
+ #: ../includes/Settings.class.php:418
209
+ msgid "Select today or soonest valid date"
210
+ msgstr "Kies vandaag of eerstvolgende geldige datum"
 
 
 
211
 
212
+ #: ../includes/Settings.class.php:419
213
+ msgid "Leave empty"
214
+ msgstr "Laat leeg"
 
 
 
215
 
216
+ #: ../includes/Settings.class.php:430
217
+ msgid "Time Interval"
218
+ msgstr "Tijdsintervak"
 
219
 
220
+ #: ../includes/Settings.class.php:431
221
+ msgid "Select the number of minutes between each available time."
222
+ msgstr "Selecteer het aantal minuten tussen elke beschikbare tijd."
 
223
 
224
+ #: ../includes/Settings.class.php:434
225
+ msgid "Every 30 minutes"
226
+ msgstr "Elke 30 minuten"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
+ #: ../includes/Settings.class.php:435
229
+ msgid "Every 15 minutes"
230
+ msgstr "Elke 15 minuten"
 
 
 
 
231
 
232
+ #: ../includes/Settings.class.php:436
233
+ msgid "Every 10 minutes"
234
+ msgstr "Elke 10 minuten"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
+ #: ../includes/Settings.class.php:437
237
+ msgid "Every 5 minutes"
238
+ msgstr "Elke 5 minuten"
 
 
 
 
239
 
240
+ #: ../includes/Settings.class.php:446
241
+ msgid "Notifications"
242
+ msgstr "Notificaties"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
+ #: ../includes/Settings.class.php:457
245
+ msgid "Reply-To Name"
246
+ msgstr "Reply-To Naam"
 
 
 
 
247
 
248
+ #: ../includes/Settings.class.php:458
249
+ msgid "The name which should appear in the Reply-To field of a notification email"
250
+ msgstr "De naam die in het veld Reply-To van een notificatiemail moet verschijnen"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
+ #: ../includes/Settings.class.php:469
253
+ msgid "Reply-To Email Address"
254
+ msgstr "Reply-To Email Adres"
255
 
256
+ #: ../includes/Settings.class.php:470
257
+ msgid ""
258
+ "The email address which should appear in the Reply-To field of a "
259
+ "notification email."
260
  msgstr ""
261
+ "Het e-mailadres, die in het veld Reply-To van een e-mail notificatie moeten "
262
+ "verschijnen."
263
 
264
+ #: ../includes/Settings.class.php:481
265
+ msgid "Admin Notification"
266
+ msgstr "Admin Notificatie"
267
 
268
+ #: ../includes/Settings.class.php:482
269
  msgid ""
270
+ "Send an email notification to an administrator when a new booking is "
271
+ "requested."
272
  msgstr ""
273
+ "Stuur een e-mailbericht naar een beheerder wanneer een nieuwe reservering "
274
+ "wordt gevraagd."
275
 
276
+ #: ../includes/Settings.class.php:492
277
+ msgid "Admin Email Address"
278
+ msgstr "Admin Email Adres"
279
 
280
+ #: ../includes/Settings.class.php:493
281
+ msgid "The email address where admin notifications should be sent."
282
+ msgstr "Het e-mailadres waar admin notificaties moeten worden toegezonden."
283
+
284
+ #: ../includes/Settings.class.php:502
285
+ msgid "Email Templates"
286
+ msgstr "Email Templates"
287
+
288
+ #: ../includes/Settings.class.php:516
289
+ msgid "Template Tags"
290
+ msgstr "Template Tags"
291
+
292
+ #: ../includes/Settings.class.php:518
293
  msgid ""
294
+ "Use the following tags to automatically add booking information to the "
295
+ "emails."
296
  msgstr ""
297
+ "Gebruik de volgende tags om automatisch reserveringsinformatie aan de e-"
298
+ "mails toe te voegen."
299
 
300
+ #: ../includes/Settings.class.php:520
301
+ msgid "Name of the user who made the booking"
302
+ msgstr "Naam van de gebruiker die de reservering heeft gedaan"
303
 
304
+ #: ../includes/Settings.class.php:523
305
+ msgid "Number of people booked"
306
+ msgstr "Aantal personen voor de reservering"
307
 
308
+ #: ../includes/Settings.class.php:526
309
+ msgid "Date and time of the booking"
310
+ msgstr "datum en tijd van de reservering"
311
 
312
+ #: ../includes/Settings.class.php:529
313
+ msgid "Phone number if supplied with the request"
314
+ msgstr "Telefoonnummer als het is opgegeven in de aanvraag"
315
 
316
+ #: ../includes/Settings.class.php:532
317
+ msgid "Message added to the request"
318
+ msgstr "Bericht van de reserveringsaanvraag"
 
 
319
 
320
+ #: ../includes/Settings.class.php:535
321
+ msgid "A link to the admin panel showing pending bookings"
322
+ msgstr "A link to the admin panel showing pending bookings"
323
 
324
+ #: ../includes/Settings.class.php:538
325
+ msgid "A link to confirm this booking. Only include this in admin notifications"
326
+ msgstr "A link to confirm this booking. Only include this in admin notifications"
 
 
327
 
328
+ #: ../includes/Settings.class.php:541
329
+ msgid "A link to reject this booking. Only include this in admin notifications"
330
+ msgstr "A link to reject this booking. Only include this in admin notifications"
331
 
332
+ #: ../includes/Settings.class.php:544
333
+ msgid "The name of this website"
334
+ msgstr "De naam van deze website"
 
 
335
 
336
+ #: ../includes/Settings.class.php:547
337
+ msgid "A link to this website"
338
+ msgstr "Een link naar deze website"
339
 
340
+ #: ../includes/Settings.class.php:550
341
+ msgid "Current date and time"
342
+ msgstr "Huidige datum en tijd"
343
 
344
+ #: ../includes/Settings.class.php:561
345
+ msgid "Admin Notification Subject"
346
+ msgstr "Admin notificatie onderwerp"
347
 
348
+ #: ../includes/Settings.class.php:562
349
+ msgid "The email subject for admin notifications."
350
+ msgstr "The email subject for admin notifications."
 
351
 
352
+ #: ../includes/Settings.class.php:573
353
+ msgid "Admin Notification Email"
354
+ msgstr "Admin Notificatie Email"
 
355
 
356
+ #: ../includes/Settings.class.php:574
357
+ msgid ""
358
+ "Enter the email an admin should receive when an initial booking request is "
359
+ "made."
360
  msgstr ""
361
+ "Voer het email adresin dat de admin moet ontvangen wanneer de "
362
+ "reserveringsaanvraag is geinitieerd"
363
 
364
+ #: ../includes/Settings.class.php:585
365
+ msgid "New Request Email Subject"
366
+ msgstr "Nieuwe aanvraag email onderwerp"
 
367
 
368
+ #: ../includes/Settings.class.php:586
369
+ msgid ""
370
+ "The email subject a user should receive when they make an initial booking "
371
+ "request."
372
  msgstr ""
373
+ "Voer het email onderwerp in dat de aanvrager moet ontvangen wanneer de "
374
+ "reserveringsaanvraag is geinitieerd"
375
 
376
+ #: ../includes/Settings.class.php:597
377
+ msgid "New Request Email"
378
+ msgstr "Nieuwe aanvraag email"
 
379
 
380
+ #: ../includes/Settings.class.php:598
381
+ msgid ""
382
+ "Enter the email a user should receive when they make an initial booking "
383
+ "request."
384
  msgstr ""
385
 
386
+ #: ../includes/Settings.class.php:609
387
+ msgid "Confirmed Email Subject"
388
  msgstr ""
389
 
390
+ #: ../includes/Settings.class.php:610
391
  msgid ""
392
+ "The email subject a user should receive when their booking has been "
393
+ "confirmed."
394
  msgstr ""
395
 
396
+ #: ../includes/Settings.class.php:621
397
+ msgid "Confirmed Email"
 
398
  msgstr ""
399
 
400
+ #: ../includes/Settings.class.php:622
401
+ msgid "Enter the email a user should receive when their booking has been confirmed."
402
  msgstr ""
403
 
404
+ #: ../includes/Settings.class.php:633
405
+ msgid "Rejected Email Subject"
406
  msgstr ""
407
 
408
+ #: ../includes/Settings.class.php:634
409
+ msgid "The email subject a user should receive when their booking has been rejected."
410
  msgstr ""
411
 
412
+ #: ../includes/Settings.class.php:645
413
+ msgid "Rejected Email"
414
  msgstr ""
415
 
416
+ #: ../includes/Settings.class.php:646
417
+ msgid "Enter the email a user should receive when their booking has been rejected."
418
  msgstr ""
419
 
420
+ #: ../restaurant-reservations.php:127
421
+ msgid "Booking Manager"
422
+ msgstr "Reserverings Manager"
423
 
424
+ #: ../restaurant-reservations.php:155
425
+ msgctxt "Title of admin page that lists bookings"
426
+ msgid "Bookings"
427
+ msgstr "Reserveringen"
428
 
429
+ #: ../restaurant-reservations.php:156
430
+ msgctxt "Title of bookings admin menu item"
431
+ msgid "Bookings"
432
+ msgstr "Reserveringen"
433
 
434
+ #: ../restaurant-reservations.php:178
435
+ msgid "Restaurant Bookings"
436
+ msgstr "Restaurant reserveringen"
437
+
438
+ #: ../restaurant-reservations.php:279
439
+ msgid "View the help documentation for Restaurant Reservations"
440
+ msgstr "Bekijk de help documentatie voor Restaurant Reservations"
441
 
442
+ #: ../restaurant-reservations.php:279
443
+ msgid "Help"
444
+ msgstr "Help"
445
 
446
+ #: ../includes/Booking.class.php:154
447
+ msgid "Please enter the date you would like to book."
448
+ msgstr "Vult u uw gewenste reserveringsdatum in"
449
 
450
+ #: ../includes/Booking.class.php:164
451
+ msgid ""
452
+ "The date you entered is not valid. Please select from one of the dates in "
453
+ "the calendar."
454
+ msgstr "De ingevoerde datum is niet juist. Selecteer een datum uit de kalender"
455
 
456
+ #: ../includes/Booking.class.php:175
457
+ msgid "Please enter the time you would like to book."
458
+ msgstr "Vult u uw gewenste reserveringstijdstip"
459
 
460
+ #: ../includes/Booking.class.php:185
461
+ msgid ""
462
+ "The time you entered is not valid. Please select from one of the times "
463
+ "provided."
464
+ msgstr "De ingevoerde tijd is niet juist. Selecteer een van de opgegeven tijden."
465
 
466
+ #: ../includes/Booking.class.php:204
467
+ #, php-format
468
+ msgid "Sorry, bookings can not be made more than %s days in advance."
469
+ msgstr "Sorry, reserveringen kunnen niet gedaan worden dan %s dagen van tevoren."
470
 
471
+ #: ../includes/Booking.class.php:215
472
+ msgid "Sorry, bookings can not be made in the past."
473
+ msgstr "Sorry, reserveringen kunnen niet in het verleden gedaan worden."
474
 
475
+ #: ../includes/Booking.class.php:223
476
+ #, php-format
477
+ msgid "Sorry, bookings must be made more than %s days in advance."
478
+ msgstr "Sorry, reserveringen moeten meer dan %s dagen van te voren gedaan worden."
479
 
480
+ #: ../includes/Booking.class.php:225
481
+ #, php-format
482
+ msgid "Sorry, bookings must be made more than %s hours in advance."
483
+ msgstr "Sorry, reserveringen moeten meer dan %s uur van te voren gedaan worden."
484
 
485
+ #: ../includes/Booking.class.php:227
486
+ #, php-format
487
+ msgid "Sorry, bookings must be made more than %s mings in advance."
488
+ msgstr "Sorry, reserveringen moeten meer dan %s minuten van te voren gedaan worden."
 
489
 
490
+ #: ../includes/Booking.class.php:266
491
+ msgid "Sorry, no bookings are being accepted then."
492
+ msgstr "Sorry, we kunnen op dat moment niet voor u reserveren."
493
 
494
+ #: ../includes/Booking.class.php:318
495
+ msgid "Sorry, no bookings are being accepted on that date."
496
+ msgstr "Sorry, we kunnen op die datum niet voor u reserveren."
497
 
498
+ #: ../includes/Booking.class.php:324
499
+ msgid "Sorry, no bookings are being accepted at that time."
500
+ msgstr "Sorry, we kunnen op dat tijdstip niet voor u reserveren."
501
 
502
+ #: ../includes/Booking.class.php:346
503
+ msgid "Please enter a name for this booking."
504
+ msgstr "Vult u een naam in voor uw reservering."
505
 
506
+ #: ../includes/Booking.class.php:356
507
+ msgid "Please let us know how many people will be in your party."
508
+ msgstr "Laat ons weten voor hoeveel personen u reserveerd. "
509
 
510
+ #: ../includes/Booking.class.php:370
511
+ #, php-format
512
+ msgid "We only accept bookings for parties of up to %d people."
513
+ msgstr "We kunnen alleen voor %d personen of meer reserveren."
514
 
515
+ #: ../includes/Booking.class.php:381
516
+ msgid "Please enter an email address so we can confirm your booking."
517
+ msgstr "Vult u uw emailadres in zodat we uw reservering kunnen bevestigen."
518
 
519
+ #: ../includes/CustomPostTypes.class.php:38 ../includes/CustomPostTypes.class.php:
520
+ #: 40 ../includes/CustomPostTypes.class.php:41 ../includes/WP_List_Table.
521
+ #: BookingsTable.class.php:76
522
+ msgid "Bookings"
523
+ msgstr "Reserveringen"
524
 
525
+ #: ../includes/CustomPostTypes.class.php:39 ../includes/WP_List_Table.
526
+ #: BookingsTable.class.php:75
527
+ msgid "Booking"
528
+ msgstr "Reservering"
529
 
530
+ #: ../includes/CustomPostTypes.class.php:42
531
+ msgid "Add New"
532
+ msgstr "Voeg nieuwe toe"
533
 
534
+ #: ../includes/CustomPostTypes.class.php:43
535
+ msgid "Add New Booking"
536
+ msgstr "Voeg nieuwe reservering toe"
537
 
538
+ #: ../includes/CustomPostTypes.class.php:44
539
+ msgid "Edit Booking"
540
+ msgstr "Bewerk reservering"
541
 
542
+ #: ../includes/CustomPostTypes.class.php:45
543
+ msgid "New Booking"
544
+ msgstr "Nieuwe reservering"
 
 
545
 
546
+ #: ../includes/CustomPostTypes.class.php:46
547
+ msgid "View Booking"
548
+ msgstr "Bekijk reservering"
549
 
550
+ #: ../includes/CustomPostTypes.class.php:47
551
+ msgid "Search Bookings"
552
+ msgstr "Zoek reservering"
 
 
553
 
554
+ #: ../includes/CustomPostTypes.class.php:48
555
+ msgid "No bookings found"
556
+ msgstr "Geen reserveringen gevonden"
557
 
558
+ #: ../includes/CustomPostTypes.class.php:49
559
+ msgid "No bookings found in trash"
560
+ msgstr "Geen reserveringen gevonden in de prullemand"
561
 
562
+ #: ../includes/CustomPostTypes.class.php:50
563
+ msgid "All Bookings"
564
+ msgstr "Alle reserveringen"
565
 
566
+ #: ../includes/CustomPostTypes.class.php:80
567
+ msgctxt "Booking status when it is pending review"
568
+ msgid "Pending"
569
+ msgstr "In afwachting"
570
 
571
+ #: ../includes/CustomPostTypes.class.php:86
572
+ msgctxt "Booking status for a confirmed booking"
573
+ msgid "Confirmed"
574
+ msgstr "Bevestigd"
 
575
 
576
+ #: ../includes/CustomPostTypes.class.php:93
577
+ #, php-format
578
+ msgid "Confirmed <span class=\"count\">(%s)</span>"
579
+ msgid_plural "Confirmed <span class=\"count\">(%s)</span>"
580
+ msgstr[0] ""
581
+ "Bevestigd \n"
582
+ "<span class=\"count\">(%s)</span>"
583
+ msgstr[1] ""
584
+ "Bevestigd \n"
585
+ "<span class=\"count\">(%s)</span>"
586
 
587
+ #: ../includes/CustomPostTypes.class.php:97
588
+ msgctxt "Booking status for a closed booking"
589
+ msgid "Closed"
590
+ msgstr "Gesloten"
591
 
592
+ #: ../includes/CustomPostTypes.class.php:104
593
+ #, php-format
594
+ msgid "Closed <span class=\"count\">(%s)</span>"
595
+ msgid_plural "Closed <span class=\"count\">(%s)</span>"
596
+ msgstr[0] ""
597
+ "Gesloten \n"
598
+ "<span class=\"count\">(%s)</span>"
599
+ msgstr[1] ""
600
+ "Gesloten \n"
601
+ "<span class=\"count\">(%s)</span>"
602
 
603
+ #: ../includes/Notification.class.php:87
604
+ msgid "View pending bookings"
605
+ msgstr "Bekijk nog niet bevestigde reserveringen"
606
 
607
+ #: ../includes/Notification.class.php:88
608
+ msgid "Confirm this booking"
609
+ msgstr "Bevestig deze reservering"
610
 
611
+ #: ../includes/Notification.class.php:89
612
+ msgid "Reject this booking"
613
+ msgstr "Weiger deze reservering"
614
 
615
+ #: ../includes/Settings.class.php:83
616
+ msgid ""
617
+ "Thanks, your booking request is waiting to be confirmed. Updates will be "
618
+ "sent to the email address you provided."
619
  msgstr ""
620
+ "Vriendelijk bedankt, \n"
621
+ "uw reserveringsaanvraag is in afwachting om te worden bevestigd."
622
 
623
+ #: ../includes/Settings.class.php:84
624
+ msgctxt ""
625
+ "Default date format for display. Must match formatting rules at http://amsul."
626
+ "ca/pickadate.js/date.htm#formatting-rules"
627
+ msgid "mmmm d, yyyy"
628
  msgstr ""
629
+ "d \n"
630
+ "mmmm, yyyy"
631
 
632
+ #: ../includes/Settings.class.php:85
633
+ msgctxt ""
634
+ "Default time format for display. Must match formatting rules at http://amsul."
635
+ "ca/pickadate.js/time.htm#formats"
636
+ msgid "h:i A"
637
+ msgstr "h:i A"
638
 
639
+ #: ../includes/Settings.class.php:86
640
+ msgctxt "Default interval in minutes when selecting a time."
641
+ msgid "30"
642
+ msgstr "30"
643
 
644
+ #: ../includes/Settings.class.php:96
645
+ msgctxt "Default email subject for admin notifications of new bookings"
646
+ msgid "New Booking Request"
647
+ msgstr "Nieuwe reserverings aanvraag"
648
+
649
+ #: ../includes/Settings.class.php:97
650
+ msgctxt ""
651
+ "Default email sent to the admin when a new booking request is made. The tags "
652
+ "in {brackets} will be replaced by the appropriate content and should be left "
653
+ "in place. HTML is allowed, but be aware that many email clients do not "
654
+ "handle HTML very well."
655
+ msgid ""
656
+ "A new booking request has been made at {site_name}:\n"
657
+ "\n"
658
+ "{user_name}\n"
659
+ "{party} people\n"
660
+ "{date}\n"
661
+ "\n"
662
+ "{bookings_link}\n"
663
+ "{confirm_link}\n"
664
+ "{close_link}\n"
665
+ "\n"
666
+ "&nbsp;\n"
667
+ "\n"
668
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
669
  msgstr ""
670
+ "Een nieuwe reserveringsaanvraag is gedaan op {site_name}:\n"
671
+ "\n"
672
+ "{user_name}\n"
673
+ "{party} personen\n"
674
+ "{date}\n"
675
+ "\n"
676
+ "{bookings_link}\n"
677
+ "{confirm_link}\n"
678
+ "{close_link}\n"
679
+ "\n"
680
+ "&nbsp;"
681
 
682
+ #: ../includes/Settings.class.php:115
683
+ #, php-format
684
+ msgctxt ""
685
+ "Default email subject sent to user when they request a booking. %s will be "
686
+ "replaced by the website name"
687
+ msgid "Your booking at %s is pending"
688
+ msgstr "Uw reservering voor %s is in afwachting van bevestiging"
689
 
690
+ #: ../includes/Settings.class.php:116
691
+ msgctxt ""
692
+ "Default email sent to users when they make a new booking request. The tags "
693
+ "in {brackets} will be replaced by the appropriate content and should be left "
694
+ "in place. HTML is allowed, but be aware that many email clients do not "
695
+ "handle HTML very well."
696
+ msgid ""
697
+ "Thanks {user_name},\n"
698
+ "\n"
699
+ "Your booking request is <strong>waiting to be confirmed</strong>.\n"
700
+ "\n"
701
+ "Give us a few moments to make sure that we've got space for you. You will "
702
+ "receive another email from us soon. If this request was made outside of our "
703
+ "normal working hours, we may not be able to confirm it until we're open "
704
+ "again.\n"
705
+ "\n"
706
+ "<strong>Your request details:</strong>\n"
707
+ "{user_name}\n"
708
+ "{party} people\n"
709
+ "{date}\n"
710
+ "\n"
711
+ "&nbsp;\n"
712
+ "\n"
713
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
714
  msgstr ""
715
+ "Beadankt {user_name},\n"
716
+ "\n"
717
+ "Uw reservering is <strong>wachtende op bevestiging</strong>.\n"
718
+ "\n"
719
+ "\n"
720
+ "Geef ons een momentje om te zien of we nog ruimte hebben voor u . U zal een "
721
+ "andere e-mail zo snel mogelijk van ons ontvangen. Als dit verzoek werd "
722
+ "gedaan werd buiten onze normale werktijden , kunnen we niet in staat zijn om "
723
+ "het te bevestigen totdat we weer geopend zijn.\n"
724
+ "\n"
725
+ "\n"
726
+ "<strong>Uw reservering details:</strong>\n"
727
+ "{user_name}\n"
728
+ "{party} personen\n"
729
+ "{date}\n"
730
+ "\n"
731
+ "&nbsp;\n"
732
+ "\n"
733
+ "<em>Dit bericht is verzonden door {site_link} op {current_time}.</em>"
734
 
735
+ #: ../includes/Settings.class.php:135
736
+ #, php-format
737
+ msgctxt ""
738
+ "Default email subject sent to user when their booking is confirmed. %s will "
739
+ "be replaced by the website name"
740
+ msgid "Your booking at %s is confirmed"
741
+ msgstr "Uw reservering op %s is bevestigd"
742
 
743
+ #: ../includes/Settings.class.php:136
744
+ msgctxt ""
745
+ "Default email sent to users when they make a new booking request. The tags "
746
+ "in {brackets} will be replaced by the appropriate content and should be left "
747
+ "in place. HTML is allowed, but be aware that many email clients do not "
748
+ "handle HTML very well."
749
  msgid ""
750
+ "Hi {user_name},\n"
751
+ "\n"
752
+ "Your booking request has been <strong>confirmed</strong>. We look forward to "
753
+ "seeing you soon.\n"
754
+ "\n"
755
+ "<strong>Your booking:</strong>\n"
756
+ "{user_name}\n"
757
+ "{party} people\n"
758
+ "{date}\n"
759
+ "\n"
760
+ "&nbsp;\n"
761
+ "\n"
762
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
763
  msgstr ""
764
+ "Hallo {user_name},\n"
765
+ "\n"
766
+ "Uw reservering is<strong>bevestigd</strong>. We kijken er naar julie komst "
767
+ "uit.\n"
768
+ "\n"
769
+ "<strong>Uw reservering:</strong>\n"
770
+ "{user_name}\n"
771
+ "{party} personen\n"
772
+ "{date}\n"
773
+ "\n"
774
+ "&nbsp;\n"
775
+ "\n"
776
+ "<em>\n"
777
+ "Dit bericht is verzonden door {site_link} op {current_time}.\n"
778
+ "</em>"
779
 
780
+ #: ../includes/Settings.class.php:153
781
+ #, php-format
782
+ msgctxt ""
783
+ "Default email subject sent to user when their booking is rejected. %s will "
784
+ "be replaced by the website name"
785
+ msgid "Your booking at %s was not accepted"
786
+ msgstr "Uw reservering op %s is helaas niet mogelijk"
787
 
788
+ #: ../includes/Settings.class.php:154
789
+ msgctxt ""
790
+ "Default email sent to users when they make a new booking request. The tags "
791
+ "in {brackets} will be replaced by the appropriate content and should be left "
792
+ "in place. HTML is allowed, but be aware that many email clients do not "
793
+ "handle HTML very well."
794
  msgid ""
795
+ "Hi {user_name},\n"
796
+ "\n"
797
+ "Sorry, we could not accomodate your booking request. We're full or not open "
798
+ "at the time you requested:\n"
799
+ "\n"
800
+ "{user_name}\n"
801
+ "{party} people\n"
802
+ "{date}\n"
803
+ "\n"
804
+ "&nbsp;\n"
805
+ "\n"
806
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
807
  msgstr ""
808
+ "Hallo {user_name},\n"
809
+ "\n"
810
+ "\n"
811
+ "Sorry , we kunnen uw reservering verzoek \n"
812
+ "niet \n"
813
+ "bevestigen. We zijn vol of niet geopend op het moment dat u wilde reserveren:"
814
+ "\n"
815
+ "\n"
816
+ "\n"
817
+ "{user_name}\n"
818
+ "{party} personen\n"
819
+ "{date}\n"
820
+ "\n"
821
+ "&nbsp;\n"
822
+ "\n"
823
+ "<em>\n"
824
+ "Dit bericht is verzonden door {site_link} op {current_time}.\n"
825
+ "</em>"
826
 
827
+ #: ../includes/Settings.class.php:218 ../includes/Settings.class.php:219
828
+ msgid "Settings"
829
+ msgstr "Instellingen"
830
 
831
+ #: ../includes/Settings.class.php:231
832
+ msgid "General"
833
+ msgstr "Algemeen"
 
 
834
 
835
+ #: ../includes/Settings.class.php:242
836
+ msgid "Booking Page"
837
+ msgstr "Reserveringspagina"
838
 
839
+ #: ../includes/Settings.class.php:243
840
  msgid ""
841
+ "Select a page on your site to automatically display the booking form and "
842
+ "confirmation message."
 
 
 
 
843
  msgstr ""
844
+ "Selecteer een pagina op uw site om het boekingsformulier en de bevestiging "
845
+ "automatisch weer te geven."
846
 
847
+ #: ../includes/Settings.class.php:259
848
+ msgid "Max Party Size"
849
+ msgstr "Maximum aantal personen"
850
 
851
+ #: ../includes/Settings.class.php:260
852
+ msgid ""
853
+ "Set a maximum allowed party size for bookings. Leave it empty to allow "
854
+ "parties of any size."
855
  msgstr ""
856
+ "Stel een maximum toegestaan aantal personen voor reserveringen. Laat dit "
857
+ "veld leeg om partijen van elke omvang mogelijk te maken."
858
 
859
+ #: ../includes/Settings.class.php:261
860
+ msgid "No limit"
861
+ msgstr "Geen limiet"
862
 
863
+ #: ../includes/Settings.class.php:271
864
+ msgid "Success Message"
865
+ msgstr "Bericht geslaagd"
866
 
867
+ #: ../includes/Settings.class.php:272
868
+ msgid "Enter the message to display when a booking request is made."
869
  msgstr ""
870
+ "Voer hier het bericht in dat wordt weergegeven wanneer een reservering "
871
+ "verzoek wordt ingediend."
872
 
873
  #: ../includes/template-functions.php:84
874
  msgid "Book a table"
875
+ msgstr "Reserveer een tafel "
876
 
877
  #: ../includes/template-functions.php:89 ../includes/WP_List_Table.BookingsTable.
878
  #: class.php:267 ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.
879
  #: class.php:365
880
  msgid "Date"
881
+ msgstr "Datum"
882
 
883
  #: ../includes/template-functions.php:96
884
  msgid "Time"
885
+ msgstr "Tijd"
886
 
887
  #: ../includes/template-functions.php:103 ../includes/WP_List_Table.BookingsTable.
888
  #: class.php:268
889
  msgid "Party"
890
+ msgstr "Aantal personen (vul een getal in)"
891
 
892
  #: ../includes/template-functions.php:110
893
  msgid "Contact Details"
894
+ msgstr "Contact Gegevens"
895
 
896
  #: ../includes/template-functions.php:115 ../includes/WP_List_Table.BookingsTable.
897
  #: class.php:269
898
  msgid "Name"
899
+ msgstr "Naam"
900
 
901
  #: ../includes/template-functions.php:122 ../includes/WP_List_Table.BookingsTable.
902
  #: class.php:270
903
  msgid "Email"
904
+ msgstr "Email"
905
 
906
  #: ../includes/template-functions.php:129 ../includes/WP_List_Table.BookingsTable.
907
  #: class.php:271
908
  msgid "Phone"
909
+ msgstr "Telefoonnummer"
910
 
911
  #: ../includes/template-functions.php:135
912
  msgid "Add a Message"
913
+ msgstr "Voeg een bericht toe"
914
 
915
  #: ../includes/template-functions.php:141 ../includes/WP_List_Table.BookingsTable.
916
  #: class.php:272
917
  msgid "Message"
918
+ msgstr "Bericht"
919
 
920
  #: ../includes/template-functions.php:146
921
  msgid "Request Booking"
922
+ msgstr "Vraag reservering aan"
923
 
924
  #: ../includes/WP_List_Table.BookingsTable.class.php:172 ..
925
+ #: includes/WP_List_Table.BookingsTable.class.php:235
926
  msgid "All"
927
+ msgstr "Alle"
928
 
929
  #: ../includes/WP_List_Table.BookingsTable.class.php:173
930
  msgid "Today"
931
+ msgstr "Vandaag"
932
 
933
  #: ../includes/WP_List_Table.BookingsTable.class.php:174
934
  msgid "Upcoming"
935
+ msgstr "Aanstaande"
936
 
937
  #: ../includes/WP_List_Table.BookingsTable.class.php:180
938
  msgctxt "Separator between two dates in a date range"
939
  msgid "&mdash;"
940
+ msgstr "&mdash;"
941
 
942
  #: ../includes/WP_List_Table.BookingsTable.class.php:192
943
  msgid "Start Date:"
944
+ msgstr "Start datum:"
945
 
946
  #: ../includes/WP_List_Table.BookingsTable.class.php:193
947
  msgid "Start Date"
948
+ msgstr "Start datum"
949
 
950
  #: ../includes/WP_List_Table.BookingsTable.class.php:194
951
  msgid "End Date:"
952
+ msgstr "Eind datum:"
953
 
954
  #: ../includes/WP_List_Table.BookingsTable.class.php:195
955
  msgid "End Date"
956
+ msgstr "Eind datum"
957
 
958
  #: ../includes/WP_List_Table.BookingsTable.class.php:196
959
  msgid "Apply"
960
+ msgstr "Pas toe"
961
 
962
  #: ../includes/WP_List_Table.BookingsTable.class.php:198
963
  msgid "Clear Filter"
964
+ msgstr "Verwijder filter"
965
 
966
  #: ../includes/WP_List_Table.BookingsTable.class.php:236
967
  msgid "Pending"
968
+ msgstr "In afwachting"
969
 
970
  #: ../includes/WP_List_Table.BookingsTable.class.php:237
971
  msgid "Confirmed"
972
+ msgstr "Bevestigd"
973
 
974
  #: ../includes/WP_List_Table.BookingsTable.class.php:238
975
  msgid "Closed"
976
+ msgstr "Gesloten"
977
 
978
  #: ../includes/WP_List_Table.BookingsTable.class.php:239
979
  msgid "Trash"
980
+ msgstr "Prullebak"
981
 
982
  #: ../includes/WP_List_Table.BookingsTable.class.php:273
983
  msgid "Status"
984
+ msgstr "Status"
985
 
986
  #: ../includes/WP_List_Table.BookingsTable.class.php:324
987
  msgctxt "Status label for bookings put in the trash"
988
  msgid "Trash"
989
+ msgstr "Prullebak"
990
 
991
  #: ../includes/WP_List_Table.BookingsTable.class.php:356
992
  msgid "Delete"
993
+ msgstr "Verwijder"
994
 
995
  #: ../includes/WP_List_Table.BookingsTable.class.php:357
996
  msgid "Set To Confirmed"
997
+ msgstr "Ingesteld voor bevestiging"
998
 
999
  #: ../includes/WP_List_Table.BookingsTable.class.php:358
1000
  msgid "Set To Pending Review"
1001
+ msgstr "Ingesteld in afwachting van bevestiging"
1002
 
1003
  #: ../includes/WP_List_Table.BookingsTable.class.php:359
1004
  msgid "Set To Closed"
1005
+ msgstr "Ingesteld om gesloten te worden"
1006
 
1007
  #: ../includes/WP_List_Table.BookingsTable.class.php:471
1008
  #, php-format
1009
  msgid "%d booking deleted successfully."
1010
  msgid_plural "%d bookings deleted successfully."
1011
+ msgstr[0] "%d reservering succesvol verwijderd"
1012
+ msgstr[1] "%d reserveringen succesvol verwijderd"
1013
 
1014
  #: ../includes/WP_List_Table.BookingsTable.class.php:474
1015
  #, php-format
1016
  msgid "%d booking confirmed."
1017
  msgid_plural "%d bookings confirmed."
1018
+ msgstr[0] "%d reservering bevestigd."
1019
+ msgstr[1] "%d reserveringen bevestigd."
1020
 
1021
  #: ../includes/WP_List_Table.BookingsTable.class.php:477
1022
  #, php-format
1023
  msgid "%d booking set to pending."
1024
  msgid_plural "%d bookings set to pending."
1025
+ msgstr[0] "%d reserveringsstatus is in wachtende op bevestiging."
1026
+ msgstr[1] "%d reserveringenstatus is in wachtende op bevestiging."
1027
 
1028
  #: ../includes/WP_List_Table.BookingsTable.class.php:480
1029
  #, php-format
1030
  msgid "%d booking closed."
1031
  msgid_plural "%d bookings closed."
1032
+ msgstr[0] "%d reservering gesloten."
1033
+ msgstr[1] "%d reserveringen gesloten."
1034
 
1035
  #: ../includes/WP_List_Table.BookingsTable.class.php:492
1036
  #, php-format
1037
  msgid "%d booking had errors and could not be processed."
1038
  msgid_plural "%d bookings had errors and could not be processed."
1039
+ msgstr[0] "%d uw reservering heeft fouten en kan niet worden verwerkt."
1040
+ msgstr[1] "%d uw reserveringen heben fouten en kunnen niet worden verwerkt."
1041
 
1042
  #: ../includes/WP_Widget.BookingFormWidget.class.php:25
1043
  msgid "Booking Form"
1044
+ msgstr "Reserveringsformulier"
1045
 
1046
  #: ../includes/WP_Widget.BookingFormWidget.class.php:26
1047
  msgid "Display a form to accept bookings."
1048
+ msgstr "Toon een formulier om reserveringen te aanvaarden."
1049
 
1050
  #: ../includes/WP_Widget.BookingFormWidget.class.php:64
1051
  msgid "Title"
1052
+ msgstr "Titel"
1053
 
1054
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:266
1055
  msgid "Add new scheduling rule"
1056
+ msgstr "Voeg een nieuwe planningsregel toe"
1057
 
1058
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:293 ..
1059
+ #: lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:306
1060
  msgctxt "Format of a scheduling rule"
1061
  msgid "Weekly"
1062
+ msgstr "Wekelijks"
1063
 
1064
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:295 ..
1065
+ #: lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:314
1066
  msgctxt "Format of a scheduling rule"
1067
  msgid "Monthly"
1068
+ msgstr "Maandelijks"
1069
 
1070
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:297 ..
1071
+ #: lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:322
1072
  msgctxt "Format of a scheduling rule"
1073
  msgid "Date"
1074
+ msgstr "Datum"
1075
 
1076
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:333
1077
  msgctxt "Label for selecting days of the week in a scheduling rule"
1078
  msgid "Days of the week"
1079
+ msgstr "Dagen van de week"
1080
 
1081
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:349
1082
  msgctxt "Label for selecting weeks of the month in a scheduling rule"
1083
  msgid "Weeks of the month"
1084
+ msgstr "Weken van de maand"
1085
 
1086
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:380
1087
  msgctxt "Label to select time slot for a scheduling rule"
1088
  msgid "Time"
1089
+ msgstr "Tijd"
1090
 
1091
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:385
1092
  msgctxt "Label to set a scheduling rule to last all day"
1093
  msgid "All day"
1094
+ msgstr "Gehele dag"
1095
 
1096
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:394
1097
  msgctxt "Label for the starting time of a scheduling rule"
1098
  msgid "Start"
1099
+ msgstr "Start"
1100
 
1101
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:402
1102
  msgctxt "Label for the ending time of a scheduling rule"
1103
  msgid "End"
1104
+ msgstr "Eind"
1105
 
1106
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:411
1107
  msgctxt "Prompt displayed when a scheduling rule is set without any time restrictions."
1109
  "All day long. Want to <a href=\"#\" data-format=\"time-slot\">set a time "
1110
  "slot</a>?"
1111
  msgstr ""
1112
+ "Ghele dag. Wilt u <a href=\"#\" data-format=\"time-slot\">een tijdsperiode "
1113
+ "instellen</a>?"
1114
 
1115
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:430 ..
1116
+ #: lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:433
1117
  msgid "Open and close this rule"
1118
+ msgstr "Openen en sluiten van deze regel"
1119
 
1120
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:436
1121
  msgid "Delete rule"
1122
+ msgstr "Verwijder regel"
1123
 
1124
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:439
1125
  msgid "Delete scheduling rule"
1126
+ msgstr "Verwijder planningsregel"
1127
 
1128
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:523
1129
  msgctxt ""
1130
  "Brief default description of a scheduling rule when no weekdays or weeks are "
1131
  "included in the rule."
1132
  msgid "Never"
1133
+ msgstr "Nooit"
1134
 
1135
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:524
1136
  msgctxt ""
1137
  "Brief default description of a scheduling rule when all the weekdays/weeks "
1138
  "are included in the rule."
1139
  msgid "Every day"
1140
+ msgstr "Elke dag"
1141
 
1142
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:525
1143
  msgctxt ""
1147
  "first one) and weeks (the second one) in the following format: M, T, W on "
1148
  "the first, second week of the month"
1149
  msgid "{days} on the {weeks} week of the month"
1150
+ msgstr "{days} van de {weeks} week van de maand"
1151
 
1152
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:526
1153
  msgctxt ""
1156
  "and will be replaced by a comma-separated list of weeks (the second one) in "
1157
  "the following format: First, second week of the month"
1158
  msgid "{weeks} week of the month"
1159
+ msgstr "{weeks} week van de maand"
1160
 
1161
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:527
1162
  msgctxt "Brief default description of a scheduling rule when no times are set"
1163
  msgid "All day"
1164
+ msgstr "Elke dag"
1165
 
1166
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:528
1167
  msgctxt ""
1168
  "Brief default description of a scheduling rule when an end time is set but "
1169
  "no start time. If the end time is 6pm, it will read: Ends at 6pm."
1170
  msgid "Ends at"
1171
+ msgstr "Eindigd op"
1172
 
1173
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:529
1174
  msgctxt ""
1175
  "Brief default description of a scheduling rule when a start time is set but "
1176
  "no end time. If the start time is 6pm, it will read: Starts at 6pm."
1177
  msgid "Starts at"
1178
+ msgstr "Begint op"
1179
 
1180
  #: ../lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php:530
1181
  msgctxt "Default separator between times of a scheduling rule."
1182
  msgid "&mdash;"
1183
+ msgstr "&mdash;"
languages/restaurant-reservations.pot ADDED
@@ -0,0 +1,1263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2015 Restaurant Reservations
2
+ # This file is distributed under the same license as the Restaurant Reservations package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Restaurant Reservations 1.2.3\n"
6
+ "Report-Msgid-Bugs-To: "
7
+ "http://wordpress.org/support/plugin/restaurant-reservations\n"
8
+ "POT-Creation-Date: 2015-01-23 11:25:35+00:00\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=utf-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "X-Generator: grunt-wp-i18n 0.4.9\n"
16
+ "X-Poedit-KeywordsList: "
17
+ "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
18
+ "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
19
+ "Language: en\n"
20
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
21
+ "X-Poedit-Country: United States\n"
22
+ "X-Poedit-SourceCharset: UTF-8\n"
23
+ "X-Poedit-Basepath: ../\n"
24
+ "X-Poedit-SearchPath-0: .\n"
25
+ "X-Poedit-Bookmarks: \n"
26
+ "X-Textdomain-Support: yes\n"
27
+
28
+ #: includes/Addons.class.php:98
29
+ #: includes/WP_List_Table.BookingsTable.class.php:310
30
+ msgid "Loading"
31
+ msgstr ""
32
+
33
+ #: includes/Addons.class.php:135
34
+ msgid "Addons for Restaurant Reservations"
35
+ msgstr ""
36
+
37
+ #: includes/Addons.class.php:157
38
+ msgid "You have been logged out. Please login again to retrieve the addons."
39
+ msgstr ""
40
+
41
+ #: includes/Addons.class.php:173
42
+ msgid ""
43
+ "You do not have permission to access this page. Please login to an "
44
+ "administrator account if you have one."
45
+ msgstr ""
46
+
47
+ #: includes/Addons.class.php:201
48
+ msgid ""
49
+ "The addons list could not be retrieved. Please <a href=\"\">try again</a>. "
50
+ "If the problem persists over time, please report it on the <a "
51
+ "href=\"http://wordpress.org/support/plugin/restaurant-reservations\" "
52
+ "target=\"_blank\">support forums</a>."
53
+ msgstr ""
54
+
55
+ #: includes/AdminBookings.class.php:65
56
+ msgid "Restaurant Bookings"
57
+ msgstr ""
58
+
59
+ #: includes/AdminBookings.class.php:66 includes/CustomPostTypes.class.php:42
60
+ msgid "Add New"
61
+ msgstr ""
62
+
63
+ #: includes/AdminBookings.class.php:111 restaurant-reservations.php:217
64
+ msgid "Add Booking"
65
+ msgstr ""
66
+
67
+ #: includes/AdminBookings.class.php:114
68
+ msgid "Cancel"
69
+ msgstr ""
70
+
71
+ #: includes/AdminBookings.class.php:128
72
+ msgid "Close"
73
+ msgstr ""
74
+
75
+ #: includes/AdminBookings.class.php:194
76
+ msgid "Booking Status"
77
+ msgstr ""
78
+
79
+ #: includes/AdminBookings.class.php:202
80
+ msgid "Send notifications"
81
+ msgstr ""
82
+
83
+ #: includes/AdminBookings.class.php:207
84
+ msgid "Learn more"
85
+ msgstr ""
86
+
87
+ #: includes/AdminBookings.class.php:208
88
+ msgid ""
89
+ "When adding a booking or changing a booking's status with this form, no "
90
+ "email notifications will be sent. Check this option if you want to send "
91
+ "email notifications."
92
+ msgstr ""
93
+
94
+ #: includes/AdminBookings.class.php:262
95
+ msgid "You have been logged out. Please %slogin again%s."
96
+ msgstr ""
97
+
98
+ #: includes/AdminBookings.class.php:298
99
+ msgid ""
100
+ "This booking has been sent to the %sTrash%s where it can not be edited. Set "
101
+ "the booking to Pending or Confirmed to edit it."
102
+ msgstr ""
103
+
104
+ #: includes/AdminBookings.class.php:315
105
+ msgid "The booking could not be retrieved. Please reload the page and try again."
106
+ msgstr ""
107
+
108
+ #: includes/AdminBookings.class.php:383
109
+ msgid ""
110
+ "Unable to trash this post. Please try again. If you continue to have "
111
+ "trouble, please refresh the page."
112
+ msgstr ""
113
+
114
+ #: includes/Booking.class.php:178
115
+ msgid "Please enter the date you would like to book."
116
+ msgstr ""
117
+
118
+ #: includes/Booking.class.php:188
119
+ msgid ""
120
+ "The date you entered is not valid. Please select from one of the dates in "
121
+ "the calendar."
122
+ msgstr ""
123
+
124
+ #: includes/Booking.class.php:199
125
+ msgid "Please enter the time you would like to book."
126
+ msgstr ""
127
+
128
+ #: includes/Booking.class.php:209
129
+ msgid ""
130
+ "The time you entered is not valid. Please select from one of the times "
131
+ "provided."
132
+ msgstr ""
133
+
134
+ #: includes/Booking.class.php:226
135
+ msgid "Sorry, bookings can not be made more than %s days in advance."
136
+ msgstr ""
137
+
138
+ #: includes/Booking.class.php:237
139
+ msgid "Sorry, bookings can not be made in the past."
140
+ msgstr ""
141
+
142
+ #: includes/Booking.class.php:245
143
+ msgid "Sorry, bookings must be made more than %s days in advance."
144
+ msgstr ""
145
+
146
+ #: includes/Booking.class.php:247
147
+ msgid "Sorry, bookings must be made more than %s hours in advance."
148
+ msgstr ""
149
+
150
+ #: includes/Booking.class.php:249
151
+ msgid "Sorry, bookings must be made more than %s mings in advance."
152
+ msgstr ""
153
+
154
+ #: includes/Booking.class.php:288
155
+ msgid "Sorry, no bookings are being accepted then."
156
+ msgstr ""
157
+
158
+ #: includes/Booking.class.php:340
159
+ msgid "Sorry, no bookings are being accepted on that date."
160
+ msgstr ""
161
+
162
+ #: includes/Booking.class.php:346
163
+ msgid "Sorry, no bookings are being accepted at that time."
164
+ msgstr ""
165
+
166
+ #: includes/Booking.class.php:368
167
+ msgid "Please enter a name for this booking."
168
+ msgstr ""
169
+
170
+ #: includes/Booking.class.php:378
171
+ msgid "Please let us know how many people will be in your party."
172
+ msgstr ""
173
+
174
+ #: includes/Booking.class.php:388
175
+ msgid "We only accept bookings for parties of up to %d people."
176
+ msgstr ""
177
+
178
+ #: includes/Booking.class.php:399
179
+ msgid "Please enter an email address so we can confirm your booking."
180
+ msgstr ""
181
+
182
+ #: includes/Booking.class.php:421
183
+ msgid "Please complete this field to request a booking."
184
+ msgstr ""
185
+
186
+ #: includes/CustomPostTypes.class.php:38 includes/CustomPostTypes.class.php:40
187
+ #: includes/CustomPostTypes.class.php:41
188
+ #: includes/WP_List_Table.BookingsTable.class.php:76
189
+ msgid "Bookings"
190
+ msgstr ""
191
+
192
+ #: includes/CustomPostTypes.class.php:39
193
+ #: includes/WP_List_Table.BookingsTable.class.php:75
194
+ msgid "Booking"
195
+ msgstr ""
196
+
197
+ #: includes/CustomPostTypes.class.php:43
198
+ msgid "Add New Booking"
199
+ msgstr ""
200
+
201
+ #: includes/CustomPostTypes.class.php:44 restaurant-reservations.php:218
202
+ msgid "Edit Booking"
203
+ msgstr ""
204
+
205
+ #: includes/CustomPostTypes.class.php:45
206
+ msgid "New Booking"
207
+ msgstr ""
208
+
209
+ #: includes/CustomPostTypes.class.php:46
210
+ msgid "View Booking"
211
+ msgstr ""
212
+
213
+ #: includes/CustomPostTypes.class.php:47
214
+ msgid "Search Bookings"
215
+ msgstr ""
216
+
217
+ #: includes/CustomPostTypes.class.php:48
218
+ msgid "No bookings found"
219
+ msgstr ""
220
+
221
+ #: includes/CustomPostTypes.class.php:49
222
+ msgid "No bookings found in trash"
223
+ msgstr ""
224
+
225
+ #: includes/CustomPostTypes.class.php:50
226
+ msgid "All Bookings"
227
+ msgstr ""
228
+
229
+ #: includes/CustomPostTypes.class.php:93
230
+ msgid "Confirmed <span class=\"count\">(%s)</span>"
231
+ msgid_plural "Confirmed <span class=\"count\">(%s)</span>"
232
+ msgstr[0] ""
233
+ msgstr[1] ""
234
+
235
+ #: includes/CustomPostTypes.class.php:104
236
+ msgid "Closed <span class=\"count\">(%s)</span>"
237
+ msgid_plural "Closed <span class=\"count\">(%s)</span>"
238
+ msgstr[0] ""
239
+ msgstr[1] ""
240
+
241
+ #: includes/Notification.class.php:88
242
+ msgid "View pending bookings"
243
+ msgstr ""
244
+
245
+ #: includes/Notification.class.php:89
246
+ msgid "Confirm this booking"
247
+ msgstr ""
248
+
249
+ #: includes/Notification.class.php:90
250
+ msgid "Reject this booking"
251
+ msgstr ""
252
+
253
+ #: includes/Settings.class.php:218 includes/Settings.class.php:219
254
+ msgid "Settings"
255
+ msgstr ""
256
+
257
+ #: includes/Settings.class.php:231
258
+ msgid "General"
259
+ msgstr ""
260
+
261
+ #: includes/Settings.class.php:242
262
+ msgid "Booking Page"
263
+ msgstr ""
264
+
265
+ #: includes/Settings.class.php:243
266
+ msgid ""
267
+ "Select a page on your site to automatically display the booking form and "
268
+ "confirmation message."
269
+ msgstr ""
270
+
271
+ #: includes/Settings.class.php:259
272
+ msgid "Max Party Size"
273
+ msgstr ""
274
+
275
+ #: includes/Settings.class.php:260
276
+ msgid "Set a maximum allowed party size for bookings."
277
+ msgstr ""
278
+
279
+ #: includes/Settings.class.php:272
280
+ msgid "Success Message"
281
+ msgstr ""
282
+
283
+ #: includes/Settings.class.php:273
284
+ msgid "Enter the message to display when a booking request is made."
285
+ msgstr ""
286
+
287
+ #: includes/Settings.class.php:284
288
+ msgid "Date Format"
289
+ msgstr ""
290
+
291
+ #: includes/Settings.class.php:285
292
+ msgid ""
293
+ "Define how the date is formatted on the booking form. %sFormatting rules%s. "
294
+ "This only changes the format on the booking form. To change the date format "
295
+ "in notification messages, modify your general %sWordPress Settings%s."
296
+ msgstr ""
297
+
298
+ #: includes/Settings.class.php:296
299
+ msgid "Time Format"
300
+ msgstr ""
301
+
302
+ #: includes/Settings.class.php:297
303
+ msgid ""
304
+ "Define how the time is formatted on the booking form. %sFormatting rules%s. "
305
+ "This only changes the format on the booking form. To change the time format "
306
+ "in notification messages, modify your general %sWordPress Settings%s."
307
+ msgstr ""
308
+
309
+ #: includes/Settings.class.php:310
310
+ msgid "Language"
311
+ msgstr ""
312
+
313
+ #: includes/Settings.class.php:311
314
+ msgid ""
315
+ "Select a language to use for the booking form datepicker if it is different "
316
+ "than your WordPress language setting."
317
+ msgstr ""
318
+
319
+ #: includes/Settings.class.php:321
320
+ msgid "Booking Schedule"
321
+ msgstr ""
322
+
323
+ #: includes/Settings.class.php:328
324
+ msgid "Add new scheduling rule"
325
+ msgstr ""
326
+
327
+ #: includes/Settings.class.php:342
328
+ msgid "Delete scheduling rule"
329
+ msgstr ""
330
+
331
+ #: includes/Settings.class.php:359
332
+ msgid "Schedule"
333
+ msgstr ""
334
+
335
+ #: includes/Settings.class.php:360
336
+ msgid "Define the weekly schedule during which you accept bookings."
337
+ msgstr ""
338
+
339
+ #: includes/Settings.class.php:385
340
+ msgid "Exceptions"
341
+ msgstr ""
342
+
343
+ #: includes/Settings.class.php:386
344
+ msgid ""
345
+ "Define special opening hours for holidays, events or other needs. Leave the "
346
+ "time empty if you're closed all day."
347
+ msgstr ""
348
+
349
+ #: includes/Settings.class.php:401
350
+ msgid "Early Bookings"
351
+ msgstr ""
352
+
353
+ #: includes/Settings.class.php:402
354
+ msgid "Select how early customers can make their booking."
355
+ msgstr ""
356
+
357
+ #: includes/Settings.class.php:405
358
+ msgid "Any time"
359
+ msgstr ""
360
+
361
+ #: includes/Settings.class.php:406
362
+ msgid "Up to 1 day in advance"
363
+ msgstr ""
364
+
365
+ #: includes/Settings.class.php:407
366
+ msgid "Up to 1 week in advance"
367
+ msgstr ""
368
+
369
+ #: includes/Settings.class.php:408
370
+ msgid "Up to 2 weeks in advance"
371
+ msgstr ""
372
+
373
+ #: includes/Settings.class.php:409
374
+ msgid "Up to 30 days in advance"
375
+ msgstr ""
376
+
377
+ #: includes/Settings.class.php:410
378
+ msgid "Up to 90 days in advance"
379
+ msgstr ""
380
+
381
+ #: includes/Settings.class.php:421
382
+ msgid "Late Bookings"
383
+ msgstr ""
384
+
385
+ #: includes/Settings.class.php:422
386
+ msgid "Select how late customers can make their booking."
387
+ msgstr ""
388
+
389
+ #: includes/Settings.class.php:425
390
+ msgid "Up to the last minute"
391
+ msgstr ""
392
+
393
+ #: includes/Settings.class.php:426
394
+ msgid "At least 15 minutes in advance"
395
+ msgstr ""
396
+
397
+ #: includes/Settings.class.php:427
398
+ msgid "At least 30 minutes in advance"
399
+ msgstr ""
400
+
401
+ #: includes/Settings.class.php:428
402
+ msgid "At least 45 minutes in advance"
403
+ msgstr ""
404
+
405
+ #: includes/Settings.class.php:429
406
+ msgid "At least 1 hour in advance"
407
+ msgstr ""
408
+
409
+ #: includes/Settings.class.php:430
410
+ msgid "At least 4 hours in advance"
411
+ msgstr ""
412
+
413
+ #: includes/Settings.class.php:431
414
+ msgid "At least 1 day in advance"
415
+ msgstr ""
416
+
417
+ #: includes/Settings.class.php:442
418
+ msgid "Date Pre-selection"
419
+ msgstr ""
420
+
421
+ #: includes/Settings.class.php:443
422
+ msgid ""
423
+ "When the booking form is loaded, should it automatically attempt to select "
424
+ "a valid date?"
425
+ msgstr ""
426
+
427
+ #: includes/Settings.class.php:446
428
+ msgid "Select today if valid"
429
+ msgstr ""
430
+
431
+ #: includes/Settings.class.php:447
432
+ msgid "Select today or next valid date"
433
+ msgstr ""
434
+
435
+ #: includes/Settings.class.php:448
436
+ msgid "Leave empty"
437
+ msgstr ""
438
+
439
+ #: includes/Settings.class.php:459
440
+ msgid "Time Interval"
441
+ msgstr ""
442
+
443
+ #: includes/Settings.class.php:460
444
+ msgid "Select the number of minutes between each available time."
445
+ msgstr ""
446
+
447
+ #: includes/Settings.class.php:463
448
+ msgid "Every 30 minutes"
449
+ msgstr ""
450
+
451
+ #: includes/Settings.class.php:464
452
+ msgid "Every 15 minutes"
453
+ msgstr ""
454
+
455
+ #: includes/Settings.class.php:465
456
+ msgid "Every 10 minutes"
457
+ msgstr ""
458
+
459
+ #: includes/Settings.class.php:466
460
+ msgid "Every 5 minutes"
461
+ msgstr ""
462
+
463
+ #: includes/Settings.class.php:475
464
+ msgid "Notifications"
465
+ msgstr ""
466
+
467
+ #: includes/Settings.class.php:486
468
+ msgid "Reply-To Name"
469
+ msgstr ""
470
+
471
+ #: includes/Settings.class.php:487
472
+ msgid ""
473
+ "The name which should appear in the Reply-To field of a user notification "
474
+ "email"
475
+ msgstr ""
476
+
477
+ #: includes/Settings.class.php:498
478
+ msgid "Reply-To Email Address"
479
+ msgstr ""
480
+
481
+ #: includes/Settings.class.php:499
482
+ msgid ""
483
+ "The email address which should appear in the Reply-To field of a user "
484
+ "notification email."
485
+ msgstr ""
486
+
487
+ #: includes/Settings.class.php:510
488
+ msgid "Admin Notification"
489
+ msgstr ""
490
+
491
+ #: includes/Settings.class.php:511
492
+ msgid ""
493
+ "Send an email notification to an administrator when a new booking is "
494
+ "requested."
495
+ msgstr ""
496
+
497
+ #: includes/Settings.class.php:521
498
+ msgid "Admin Email Address"
499
+ msgstr ""
500
+
501
+ #: includes/Settings.class.php:522
502
+ msgid "The email address where admin notifications should be sent."
503
+ msgstr ""
504
+
505
+ #: includes/Settings.class.php:531
506
+ msgid "Email Templates"
507
+ msgstr ""
508
+
509
+ #: includes/Settings.class.php:533
510
+ msgid ""
511
+ "Adjust the messages that are emailed to users and admins during the booking "
512
+ "process."
513
+ msgstr ""
514
+
515
+ #: includes/Settings.class.php:543
516
+ msgid "Template Tags"
517
+ msgstr ""
518
+
519
+ #: includes/Settings.class.php:545
520
+ msgid ""
521
+ "Use the following tags to automatically add booking information to the "
522
+ "emails. Tags labeled with an asterisk (*) can be used in the email subject "
523
+ "as well."
524
+ msgstr ""
525
+
526
+ #: includes/Settings.class.php:556
527
+ msgid "Admin Notification Subject"
528
+ msgstr ""
529
+
530
+ #: includes/Settings.class.php:557
531
+ msgid "The email subject for admin notifications."
532
+ msgstr ""
533
+
534
+ #: includes/Settings.class.php:568
535
+ msgid "Admin Notification Email"
536
+ msgstr ""
537
+
538
+ #: includes/Settings.class.php:569
539
+ msgid ""
540
+ "Enter the email an admin should receive when an initial booking request is "
541
+ "made."
542
+ msgstr ""
543
+
544
+ #: includes/Settings.class.php:580
545
+ msgid "New Request Email Subject"
546
+ msgstr ""
547
+
548
+ #: includes/Settings.class.php:581
549
+ msgid ""
550
+ "The email subject a user should receive when they make an initial booking "
551
+ "request."
552
+ msgstr ""
553
+
554
+ #: includes/Settings.class.php:592
555
+ msgid "New Request Email"
556
+ msgstr ""
557
+
558
+ #: includes/Settings.class.php:593
559
+ msgid ""
560
+ "Enter the email a user should receive when they make an initial booking "
561
+ "request."
562
+ msgstr ""
563
+
564
+ #: includes/Settings.class.php:604
565
+ msgid "Confirmed Email Subject"
566
+ msgstr ""
567
+
568
+ #: includes/Settings.class.php:605
569
+ msgid ""
570
+ "The email subject a user should receive when their booking has been "
571
+ "confirmed."
572
+ msgstr ""
573
+
574
+ #: includes/Settings.class.php:616
575
+ msgid "Confirmed Email"
576
+ msgstr ""
577
+
578
+ #: includes/Settings.class.php:617
579
+ msgid "Enter the email a user should receive when their booking has been confirmed."
580
+ msgstr ""
581
+
582
+ #: includes/Settings.class.php:628
583
+ msgid "Rejected Email Subject"
584
+ msgstr ""
585
+
586
+ #: includes/Settings.class.php:629
587
+ msgid ""
588
+ "The email subject a user should receive when their booking has been "
589
+ "rejected."
590
+ msgstr ""
591
+
592
+ #: includes/Settings.class.php:640
593
+ msgid "Rejected Email"
594
+ msgstr ""
595
+
596
+ #: includes/Settings.class.php:641
597
+ msgid "Enter the email a user should receive when their booking has been rejected."
598
+ msgstr ""
599
+
600
+ #: includes/Settings.class.php:659
601
+ msgid "Any size"
602
+ msgstr ""
603
+
604
+ #: includes/Settings.class.php:743
605
+ msgid "Book a table"
606
+ msgstr ""
607
+
608
+ #: includes/Settings.class.php:746
609
+ #: includes/WP_List_Table.BookingsTable.class.php:278
610
+ msgid "Date"
611
+ msgstr ""
612
+
613
+ #: includes/Settings.class.php:752
614
+ msgid "Time"
615
+ msgstr ""
616
+
617
+ #: includes/Settings.class.php:758
618
+ #: includes/WP_List_Table.BookingsTable.class.php:279
619
+ msgid "Party"
620
+ msgstr ""
621
+
622
+ #: includes/Settings.class.php:771
623
+ msgid "Contact Details"
624
+ msgstr ""
625
+
626
+ #: includes/Settings.class.php:774
627
+ #: includes/WP_List_Table.BookingsTable.class.php:280
628
+ msgid "Name"
629
+ msgstr ""
630
+
631
+ #: includes/Settings.class.php:780
632
+ #: includes/WP_List_Table.BookingsTable.class.php:281
633
+ msgid "Email"
634
+ msgstr ""
635
+
636
+ #: includes/Settings.class.php:789
637
+ #: includes/WP_List_Table.BookingsTable.class.php:282
638
+ msgid "Phone"
639
+ msgstr ""
640
+
641
+ #: includes/Settings.class.php:797
642
+ msgid "Add a Message"
643
+ msgstr ""
644
+
645
+ #: includes/Settings.class.php:802
646
+ #: includes/WP_List_Table.BookingsTable.class.php:283
647
+ msgid "Message"
648
+ msgstr ""
649
+
650
+ #: includes/Settings.class.php:847
651
+ msgid "Email of the user who made the booking"
652
+ msgstr ""
653
+
654
+ #: includes/Settings.class.php:848
655
+ msgid "* Name of the user who made the booking"
656
+ msgstr ""
657
+
658
+ #: includes/Settings.class.php:849
659
+ msgid "* Number of people booked"
660
+ msgstr ""
661
+
662
+ #: includes/Settings.class.php:850
663
+ msgid "* Date and time of the booking"
664
+ msgstr ""
665
+
666
+ #: includes/Settings.class.php:851
667
+ msgid "Phone number if supplied with the request"
668
+ msgstr ""
669
+
670
+ #: includes/Settings.class.php:852
671
+ msgid "Message added to the request"
672
+ msgstr ""
673
+
674
+ #: includes/Settings.class.php:853
675
+ msgid "A link to the admin panel showing pending bookings"
676
+ msgstr ""
677
+
678
+ #: includes/Settings.class.php:854
679
+ msgid "A link to confirm this booking. Only include this in admin notifications"
680
+ msgstr ""
681
+
682
+ #: includes/Settings.class.php:855
683
+ msgid "A link to reject this booking. Only include this in admin notifications"
684
+ msgstr ""
685
+
686
+ #: includes/Settings.class.php:856
687
+ msgid "The name of this website"
688
+ msgstr ""
689
+
690
+ #: includes/Settings.class.php:857
691
+ msgid "A link to this website"
692
+ msgstr ""
693
+
694
+ #: includes/Settings.class.php:858
695
+ msgid "Current date and time"
696
+ msgstr ""
697
+
698
+ #: includes/WP_List_Table.BookingsTable.class.php:186
699
+ msgid "Upcoming"
700
+ msgstr ""
701
+
702
+ #: includes/WP_List_Table.BookingsTable.class.php:187
703
+ msgid "Today"
704
+ msgstr ""
705
+
706
+ #: includes/WP_List_Table.BookingsTable.class.php:188
707
+ #: includes/WP_List_Table.BookingsTable.class.php:246
708
+ msgid "All"
709
+ msgstr ""
710
+
711
+ #: includes/WP_List_Table.BookingsTable.class.php:204
712
+ msgid "Start Date:"
713
+ msgstr ""
714
+
715
+ #: includes/WP_List_Table.BookingsTable.class.php:205
716
+ msgid "Start Date"
717
+ msgstr ""
718
+
719
+ #: includes/WP_List_Table.BookingsTable.class.php:206
720
+ msgid "End Date:"
721
+ msgstr ""
722
+
723
+ #: includes/WP_List_Table.BookingsTable.class.php:207
724
+ msgid "End Date"
725
+ msgstr ""
726
+
727
+ #: includes/WP_List_Table.BookingsTable.class.php:208
728
+ msgid "Apply"
729
+ msgstr ""
730
+
731
+ #: includes/WP_List_Table.BookingsTable.class.php:210
732
+ msgid "Clear Filter"
733
+ msgstr ""
734
+
735
+ #: includes/WP_List_Table.BookingsTable.class.php:247
736
+ msgid "Pending"
737
+ msgstr ""
738
+
739
+ #: includes/WP_List_Table.BookingsTable.class.php:248
740
+ msgid "Confirmed"
741
+ msgstr ""
742
+
743
+ #: includes/WP_List_Table.BookingsTable.class.php:249
744
+ msgid "Closed"
745
+ msgstr ""
746
+
747
+ #: includes/WP_List_Table.BookingsTable.class.php:250
748
+ #: includes/WP_List_Table.BookingsTable.class.php:315
749
+ msgid "Trash"
750
+ msgstr ""
751
+
752
+ #: includes/WP_List_Table.BookingsTable.class.php:284
753
+ msgid "Status"
754
+ msgstr ""
755
+
756
+ #: includes/WP_List_Table.BookingsTable.class.php:314
757
+ msgid "Edit"
758
+ msgstr ""
759
+
760
+ #: includes/WP_List_Table.BookingsTable.class.php:376
761
+ msgid "Delete"
762
+ msgstr ""
763
+
764
+ #: includes/WP_List_Table.BookingsTable.class.php:377
765
+ msgid "Set To Confirmed"
766
+ msgstr ""
767
+
768
+ #: includes/WP_List_Table.BookingsTable.class.php:378
769
+ msgid "Set To Pending Review"
770
+ msgstr ""
771
+
772
+ #: includes/WP_List_Table.BookingsTable.class.php:379
773
+ msgid "Set To Closed"
774
+ msgstr ""
775
+
776
+ #: includes/WP_List_Table.BookingsTable.class.php:494
777
+ msgid "%d booking deleted successfully."
778
+ msgid_plural "%d bookings deleted successfully."
779
+ msgstr[0] ""
780
+ msgstr[1] ""
781
+
782
+ #: includes/WP_List_Table.BookingsTable.class.php:497
783
+ msgid "%d booking confirmed."
784
+ msgid_plural "%d bookings confirmed."
785
+ msgstr[0] ""
786
+ msgstr[1] ""
787
+
788
+ #: includes/WP_List_Table.BookingsTable.class.php:500
789
+ msgid "%d booking set to pending."
790
+ msgid_plural "%d bookings set to pending."
791
+ msgstr[0] ""
792
+ msgstr[1] ""
793
+
794
+ #: includes/WP_List_Table.BookingsTable.class.php:503
795
+ msgid "%d booking closed."
796
+ msgid_plural "%d bookings closed."
797
+ msgstr[0] ""
798
+ msgstr[1] ""
799
+
800
+ #: includes/WP_List_Table.BookingsTable.class.php:515
801
+ msgid "%d booking had errors and could not be processed."
802
+ msgid_plural "%d bookings had errors and could not be processed."
803
+ msgstr[0] ""
804
+ msgstr[1] ""
805
+
806
+ #: includes/WP_List_Table.BookingsTable.class.php:691
807
+ msgid "You're viewing bookings that have been moved to the trash."
808
+ msgstr ""
809
+
810
+ #: includes/WP_List_Table.BookingsTable.class.php:700
811
+ msgid "Only today's bookings are being shown."
812
+ msgstr ""
813
+
814
+ #: includes/WP_List_Table.BookingsTable.class.php:702
815
+ msgid "Only upcoming bookings are being shown."
816
+ msgstr ""
817
+
818
+ #: includes/WP_Widget.BookingFormWidget.class.php:25
819
+ msgid "Booking Form"
820
+ msgstr ""
821
+
822
+ #: includes/WP_Widget.BookingFormWidget.class.php:26
823
+ msgid "Display a form to accept bookings."
824
+ msgstr ""
825
+
826
+ #: includes/WP_Widget.BookingFormWidget.class.php:64
827
+ msgid "Title"
828
+ msgstr ""
829
+
830
+ #: includes/template-functions.php:106
831
+ msgid "Request Booking"
832
+ msgstr ""
833
+
834
+ #: restaurant-reservations.php:148
835
+ msgid "Booking Manager"
836
+ msgstr ""
837
+
838
+ #: restaurant-reservations.php:219
839
+ msgid ""
840
+ "An unspecified error occurred. Please try again. If the problem persists, "
841
+ "try logging out and logging back in."
842
+ msgstr ""
843
+
844
+ #: restaurant-reservations.php:281
845
+ msgid "View the help documentation for Restaurant Reservations"
846
+ msgstr ""
847
+
848
+ #: restaurant-reservations.php:281
849
+ msgid "Help"
850
+ msgstr ""
851
+
852
+ #. Plugin Name of the plugin/theme
853
+ msgid "Restaurant Reservations"
854
+ msgstr ""
855
+
856
+ #. #-#-#-#-# restaurant-reservations.pot (Restaurant Reservations 1.2.3) #-#-#-#-#
857
+ #. Plugin URI of the plugin/theme
858
+ #. #-#-#-#-# restaurant-reservations.pot (Restaurant Reservations 1.2.3) #-#-#-#-#
859
+ #. Author URI of the plugin/theme
860
+ msgid "http://themeofthecrop.com"
861
+ msgstr ""
862
+
863
+ #. Description of the plugin/theme
864
+ msgid "Accept restaurant reservations and bookings online."
865
+ msgstr ""
866
+
867
+ #. Author of the plugin/theme
868
+ msgid "Theme of the Crop"
869
+ msgstr ""
870
+
871
+ #: includes/Addons.class.php:99
872
+ msgctxt "Error message when retrieving list of addons"
873
+ msgid "An unknown error occured."
874
+ msgstr ""
875
+
876
+ #: includes/Addons.class.php:100
877
+ msgctxt "Label for an addon that is already installed and activated."
878
+ msgid "Already Installed"
879
+ msgstr ""
880
+
881
+ #: includes/Addons.class.php:101
882
+ msgctxt "Label for an addon that is not yet released."
883
+ msgid "Coming Soon"
884
+ msgstr ""
885
+
886
+ #: includes/Addons.class.php:102
887
+ msgctxt "Label for an addon that is free."
888
+ msgid "Free"
889
+ msgstr ""
890
+
891
+ #: includes/Addons.class.php:103
892
+ msgctxt "Label for an addon that is released."
893
+ msgid "Get It"
894
+ msgstr ""
895
+
896
+ #: includes/Addons.class.php:117
897
+ msgctxt "Title of addons page"
898
+ msgid "Addons"
899
+ msgstr ""
900
+
901
+ #: includes/Addons.class.php:118
902
+ msgctxt "Title of addons page in the admin menu"
903
+ msgid "Addons"
904
+ msgstr ""
905
+
906
+ #: includes/AdminBookings.class.php:41
907
+ msgctxt "Title of admin page that lists bookings"
908
+ msgid "Bookings"
909
+ msgstr ""
910
+
911
+ #: includes/AdminBookings.class.php:42
912
+ msgctxt "Title of bookings admin menu item"
913
+ msgid "Bookings"
914
+ msgstr ""
915
+
916
+ #: includes/CustomPostTypes.class.php:80
917
+ msgctxt "Booking status when it is pending review"
918
+ msgid "Pending"
919
+ msgstr ""
920
+
921
+ #: includes/CustomPostTypes.class.php:86
922
+ msgctxt "Booking status for a confirmed booking"
923
+ msgid "Confirmed"
924
+ msgstr ""
925
+
926
+ #: includes/CustomPostTypes.class.php:97
927
+ msgctxt "Booking status for a closed booking"
928
+ msgid "Closed"
929
+ msgstr ""
930
+
931
+ #: includes/Settings.class.php:83
932
+ msgctxt "restaurant-reservations"
933
+ msgid ""
934
+ "Thanks, your booking request is waiting to be confirmed. Updates will be "
935
+ "sent to the email address you provided."
936
+ msgstr ""
937
+
938
+ #: includes/Settings.class.php:84
939
+ msgctxt ""
940
+ "Default date format for display. Must match formatting rules at "
941
+ "http://amsul.ca/pickadate.js/date.htm#formatting-rules"
942
+ msgid "mmmm d, yyyy"
943
+ msgstr ""
944
+
945
+ #: includes/Settings.class.php:85
946
+ msgctxt ""
947
+ "Default time format for display. Must match formatting rules at "
948
+ "http://amsul.ca/pickadate.js/time.htm#formats"
949
+ msgid "h:i A"
950
+ msgstr ""
951
+
952
+ #: includes/Settings.class.php:86
953
+ msgctxt "Default interval in minutes when selecting a time."
954
+ msgid "30"
955
+ msgstr ""
956
+
957
+ #: includes/Settings.class.php:96
958
+ msgctxt "Default email subject for admin notifications of new bookings"
959
+ msgid "New Booking Request"
960
+ msgstr ""
961
+
962
+ #: includes/Settings.class.php:97
963
+ msgctxt ""
964
+ "Default email sent to the admin when a new booking request is made. The "
965
+ "tags in {brackets} will be replaced by the appropriate content and should "
966
+ "be left in place. HTML is allowed, but be aware that many email clients do "
967
+ "not handle HTML very well."
968
+ msgid ""
969
+ "A new booking request has been made at {site_name}:\n"
970
+ "\n"
971
+ "{user_name}\n"
972
+ "{party} people\n"
973
+ "{date}\n"
974
+ "\n"
975
+ "{bookings_link}\n"
976
+ "{confirm_link}\n"
977
+ "{close_link}\n"
978
+ "\n"
979
+ "&nbsp;\n"
980
+ "\n"
981
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
982
+ msgstr ""
983
+
984
+ #: includes/Settings.class.php:115
985
+ msgctxt ""
986
+ "Default email subject sent to user when they request a booking. %s will be "
987
+ "replaced by the website name"
988
+ msgid "Your booking at %s is pending"
989
+ msgstr ""
990
+
991
+ #: includes/Settings.class.php:116
992
+ msgctxt ""
993
+ "Default email sent to users when they make a new booking request. The tags "
994
+ "in {brackets} will be replaced by the appropriate content and should be "
995
+ "left in place. HTML is allowed, but be aware that many email clients do not "
996
+ "handle HTML very well."
997
+ msgid ""
998
+ "Thanks {user_name},\n"
999
+ "\n"
1000
+ "Your booking request is <strong>waiting to be confirmed</strong>.\n"
1001
+ "\n"
1002
+ "Give us a few moments to make sure that we've got space for you. You will "
1003
+ "receive another email from us soon. If this request was made outside of our "
1004
+ "normal working hours, we may not be able to confirm it until we're open "
1005
+ "again.\n"
1006
+ "\n"
1007
+ "<strong>Your request details:</strong>\n"
1008
+ "{user_name}\n"
1009
+ "{party} people\n"
1010
+ "{date}\n"
1011
+ "\n"
1012
+ "&nbsp;\n"
1013
+ "\n"
1014
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
1015
+ msgstr ""
1016
+
1017
+ #: includes/Settings.class.php:136
1018
+ msgctxt ""
1019
+ "Default email sent to users when they make a new booking request. The tags "
1020
+ "in {brackets} will be replaced by the appropriate content and should be "
1021
+ "left in place. HTML is allowed, but be aware that many email clients do not "
1022
+ "handle HTML very well."
1023
+ msgid ""
1024
+ "Hi {user_name},\n"
1025
+ "\n"
1026
+ "Your booking request has been <strong>confirmed</strong>. We look forward "
1027
+ "to seeing you soon.\n"
1028
+ "\n"
1029
+ "<strong>Your booking:</strong>\n"
1030
+ "{user_name}\n"
1031
+ "{party} people\n"
1032
+ "{date}\n"
1033
+ "\n"
1034
+ "&nbsp;\n"
1035
+ "\n"
1036
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
1037
+ msgstr ""
1038
+
1039
+ #: includes/Settings.class.php:154
1040
+ msgctxt ""
1041
+ "Default email sent to users when they make a new booking request. The tags "
1042
+ "in {brackets} will be replaced by the appropriate content and should be "
1043
+ "left in place. HTML is allowed, but be aware that many email clients do not "
1044
+ "handle HTML very well."
1045
+ msgid ""
1046
+ "Hi {user_name},\n"
1047
+ "\n"
1048
+ "Sorry, we could not accomodate your booking request. We're full or not open "
1049
+ "at the time you requested:\n"
1050
+ "\n"
1051
+ "{user_name}\n"
1052
+ "{party} people\n"
1053
+ "{date}\n"
1054
+ "\n"
1055
+ "&nbsp;\n"
1056
+ "\n"
1057
+ "<em>This message was sent by {site_link} on {current_time}.</em>"
1058
+ msgstr ""
1059
+
1060
+ #: includes/Settings.class.php:135
1061
+ msgctxt ""
1062
+ "Default email subject sent to user when their booking is confirmed. %s will "
1063
+ "be replaced by the website name"
1064
+ msgid "Your booking at %s is confirmed"
1065
+ msgstr ""
1066
+
1067
+ #: includes/Settings.class.php:153
1068
+ msgctxt ""
1069
+ "Default email subject sent to user when their booking is rejected. %s will "
1070
+ "be replaced by the website name"
1071
+ msgid "Your booking at %s was not accepted"
1072
+ msgstr ""
1073
+
1074
+ #: includes/Settings.class.php:329
1075
+ msgctxt "Format of a scheduling rule"
1076
+ msgid "Weekly"
1077
+ msgstr ""
1078
+
1079
+ #: includes/Settings.class.php:330
1080
+ msgctxt "Format of a scheduling rule"
1081
+ msgid "Monthly"
1082
+ msgstr ""
1083
+
1084
+ #: includes/Settings.class.php:331
1085
+ msgctxt "Format of a scheduling rule"
1086
+ msgid "Date"
1087
+ msgstr ""
1088
+
1089
+ #: includes/Settings.class.php:332
1090
+ msgctxt "Label for selecting days of the week in a scheduling rule"
1091
+ msgid "Days of the week"
1092
+ msgstr ""
1093
+
1094
+ #: includes/Settings.class.php:333
1095
+ msgctxt "Label for selecting weeks of the month in a scheduling rule"
1096
+ msgid "Weeks of the month"
1097
+ msgstr ""
1098
+
1099
+ #: includes/Settings.class.php:334
1100
+ msgctxt "Label to select a date for a scheduling rule"
1101
+ msgid "Date"
1102
+ msgstr ""
1103
+
1104
+ #: includes/Settings.class.php:335
1105
+ msgctxt "Label to select a time slot for a scheduling rule"
1106
+ msgid "Time"
1107
+ msgstr ""
1108
+
1109
+ #: includes/Settings.class.php:336
1110
+ msgctxt "Label to set a scheduling rule to last all day"
1111
+ msgid "All day"
1112
+ msgstr ""
1113
+
1114
+ #: includes/Settings.class.php:337
1115
+ msgctxt "Label for the starting time of a scheduling rule"
1116
+ msgid "Start"
1117
+ msgstr ""
1118
+
1119
+ #: includes/Settings.class.php:338
1120
+ msgctxt "Label for the ending time of a scheduling rule"
1121
+ msgid "End"
1122
+ msgstr ""
1123
+
1124
+ #: includes/Settings.class.php:339
1125
+ msgctxt "Prompt displayed when a scheduling rule is set without any time restrictions"
1126
+ msgid "All day long. Want to %sset a time slot%s?"
1127
+ msgstr ""
1128
+
1129
+ #: includes/Settings.class.php:340
1130
+ msgctxt "Toggle a scheduling rule open and closed"
1131
+ msgid "Open and close this rule"
1132
+ msgstr ""
1133
+
1134
+ #: includes/Settings.class.php:341
1135
+ msgctxt "Delete a scheduling rule"
1136
+ msgid "Delete rule"
1137
+ msgstr ""
1138
+
1139
+ #: includes/Settings.class.php:343
1140
+ msgctxt ""
1141
+ "Brief default description of a scheduling rule when no weekdays or weeks "
1142
+ "are included in the rule"
1143
+ msgid "Never"
1144
+ msgstr ""
1145
+
1146
+ #: includes/Settings.class.php:344
1147
+ msgctxt ""
1148
+ "Brief default description of a scheduling rule when all the weekdays/weeks "
1149
+ "are included in the rule"
1150
+ msgid "Every day"
1151
+ msgstr ""
1152
+
1153
+ #: includes/Settings.class.php:345
1154
+ msgctxt ""
1155
+ "Brief default description of a scheduling rule when some weekdays are "
1156
+ "included on only some weeks of the month. %s should be left alone and will "
1157
+ "be replaced by a comma-separated list of days and weeks in the following "
1158
+ "format: M, T, W on the first, second week of the month"
1159
+ msgid "%s on the %s week of the month"
1160
+ msgstr ""
1161
+
1162
+ #: includes/Settings.class.php:346
1163
+ msgctxt ""
1164
+ "Brief default description of a scheduling rule when some weeks of the month "
1165
+ "are included but all or no weekdays are selected. %s should be left alone "
1166
+ "and will be replaced by a comma-separated list of weeks in the following "
1167
+ "format: First, second week of the month"
1168
+ msgid "%s week of the month"
1169
+ msgstr ""
1170
+
1171
+ #: includes/Settings.class.php:347
1172
+ msgctxt "Brief default description of a scheduling rule when no times are set"
1173
+ msgid "All day"
1174
+ msgstr ""
1175
+
1176
+ #: includes/Settings.class.php:348
1177
+ msgctxt ""
1178
+ "Brief default description of a scheduling rule when an end time is set but "
1179
+ "no start time. If the end time is 6pm, it will read: Ends at 6pm"
1180
+ msgid "Ends at"
1181
+ msgstr ""
1182
+
1183
+ #: includes/Settings.class.php:349
1184
+ msgctxt ""
1185
+ "Brief default description of a scheduling rule when a start time is set but "
1186
+ "no end time. If the start time is 6pm, it will read: Starts at 6pm"
1187
+ msgid "Starts at"
1188
+ msgstr ""
1189
+
1190
+ #: includes/Settings.class.php:350
1191
+ msgctxt "Separator between times of a scheduling rule"
1192
+ msgid "&mdash;"
1193
+ msgstr ""
1194
+
1195
+ #: includes/Settings.class.php:362
1196
+ msgctxt "Monday abbreviation"
1197
+ msgid "Mo"
1198
+ msgstr ""
1199
+
1200
+ #: includes/Settings.class.php:363
1201
+ msgctxt "Tuesday abbreviation"
1202
+ msgid "Tu"
1203
+ msgstr ""
1204
+
1205
+ #: includes/Settings.class.php:364
1206
+ msgctxt "Wednesday abbreviation"
1207
+ msgid "We"
1208
+ msgstr ""
1209
+
1210
+ #: includes/Settings.class.php:365
1211
+ msgctxt "Thursday abbreviation"
1212
+ msgid "Th"
1213
+ msgstr ""
1214
+
1215
+ #: includes/Settings.class.php:366
1216
+ msgctxt "Friday abbreviation"
1217
+ msgid "Fr"
1218
+ msgstr ""
1219
+
1220
+ #: includes/Settings.class.php:367
1221
+ msgctxt "Saturday abbreviation"
1222
+ msgid "Sa"
1223
+ msgstr ""
1224
+
1225
+ #: includes/Settings.class.php:368
1226
+ msgctxt "Sunday abbreviation"
1227
+ msgid "Su"
1228
+ msgstr ""
1229
+
1230
+ #: includes/Settings.class.php:378
1231
+ msgctxt "Brief default description of a scheduling exception when no times are set"
1232
+ msgid "Closed all day"
1233
+ msgstr ""
1234
+
1235
+ #: includes/WP_List_Table.BookingsTable.class.php:137
1236
+ #: includes/WP_List_Table.BookingsTable.class.php:139
1237
+ msgctxt ""
1238
+ "No date limit in a date range, eg 2014-* would mean any date from 2014 or "
1239
+ "after"
1240
+ msgid "*"
1241
+ msgstr ""
1242
+
1243
+ #: includes/WP_List_Table.BookingsTable.class.php:138
1244
+ msgctxt "Separator between two dates in a date range"
1245
+ msgid "&mdash;"
1246
+ msgstr ""
1247
+
1248
+ #: includes/WP_List_Table.BookingsTable.class.php:344
1249
+ msgctxt "Status label for bookings put in the trash"
1250
+ msgid "Trash"
1251
+ msgstr ""
1252
+
1253
+ #: includes/WP_List_Table.BookingsTable.class.php:693
1254
+ msgctxt ""
1255
+ "Indicates which booking status is currently being filtered in the list of "
1256
+ "bookings."
1257
+ msgid "You're viewing bookings that have been marked as %s."
1258
+ msgstr ""
1259
+
1260
+ #: includes/WP_List_Table.BookingsTable.class.php:698
1261
+ msgctxt "Notification of booking date range, eg - bookings from 2014-12-02-2014-12-05"
1262
+ msgid "Only bookings from %s are being shown."
1263
+ msgstr ""
lib/simple-admin-pages/README.md CHANGED
@@ -19,14 +19,17 @@ yet.*
19
 
20
  - Text field
21
  - Textarea field
22
- - Checkbox (single option to enable/disable setting)
23
  - Select dropdown with custom options
24
  - Select dropdown of any post type
25
  - Select dropdown of any taxonomy type
26
  - HTML Content (for instructions, links or other inert text)
 
27
 
28
  ## Controls Supported for Special Use Cases
29
 
 
 
30
  - Business Opening Hours
31
 
32
  ## Usage
@@ -38,7 +41,7 @@ Here's a simple example of how you can use this library to create an admin page.
38
  require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
39
  $sap = sap_initialize_library(
40
  array(
41
- 'version' => '2.0.a.7', // Version of the library
42
  'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
43
  )
44
  );
@@ -48,8 +51,8 @@ Here's a simple example of how you can use this library to create an admin page.
48
  'options', // Admin menu which this page should be added to
49
  array( // Array of key/value pairs matching the AdminPage class constructor variables
50
  'id' => 'basic-settings',
51
- 'title' => __( 'Page Title', SAP_TEXTDOMAIN ),
52
- 'menu_title' => __( 'menu Title', SAP_TEXTDOMAIN ),
53
  'description' => '',
54
  'capability' => 'manage_options' // User permissions access level
55
  )
@@ -60,8 +63,8 @@ Here's a simple example of how you can use this library to create an admin page.
60
  'basic-settings', // Page to add this section to
61
  array( // Array of key/value pairs matching the AdminPageSection class constructor variables
62
  'id' => 'basic-details',
63
- 'title' => __( 'Basic Details', SAP_TEXTDOMAIN ),
64
- 'description' => __( 'This section includes some basic details for you to configure.', SAP_TEXTDOMAIN )
65
  )
66
  );
67
 
@@ -72,12 +75,12 @@ Here's a simple example of how you can use this library to create an admin page.
72
  'select', // Type of setting (see sapLibrary::get_setting_classname()
73
  array(
74
  'id' => 'select-field',
75
- 'title' => __( 'Select Field', SAP_TEXTDOMAIN ),
76
- 'description' => __( 'A demonstration of the select field type.', SAP_TEXTDOMAIN ),
77
  'options' => array(
78
- 'one' => __( 'Option 1', SAP_TEXTDOMAIN ),
79
- 'two' => __( 'Option 2', SAP_TEXTDOMAIN ),
80
- 'three' => __( 'Option 3', SAP_TEXTDOMAIN )
81
  )
82
  )
83
  );
@@ -127,7 +130,7 @@ The lib_url is used to print stylesheets or scripts attached to the library.
127
  require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
128
  $sap = sap_initialize_library(
129
  $args = array(
130
- 'version' => '2.0.a.7', // Version of the library
131
  'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
132
  )
133
  );
@@ -184,8 +187,8 @@ $sap->add_page(
184
  $type,
185
  $args = array(
186
  'id' => 'my-settings',
187
- 'title' => __( 'Page Title', SAP_TEXTDOMAIN ),
188
- 'menu_title' => __( 'menu Title', SAP_TEXTDOMAIN ),
189
  'description' => '',
190
  'capability' => 'manage_options'
191
  'default_tab' => 'tab-one',
@@ -237,8 +240,8 @@ $sap->add_section(
237
  $page_id,
238
  $args = array(
239
  'id' => 'basic-details-section',
240
- 'title' => __( 'Basic Details', SAP_TEXTDOMAIN ),
241
- 'description' => __( 'This section includes some basic details for you to configure.', SAP_TEXTDOMAIN )
242
  )
243
  );
244
  ```
@@ -252,8 +255,8 @@ $sap->add_section(
252
  $page_id,
253
  $args = array(
254
  'id' => 'tab-one',
255
- 'title' => __( 'Tab One', SAP_TEXTDOMAIN ),
256
- 'description' => __( 'This tab includes some settings for you to configure.', SAP_TEXTDOMAIN ),
257
  'is_tab' => true,
258
  )
259
  );
@@ -265,8 +268,8 @@ $sap->add_section(
265
  $page_id,
266
  $args = array(
267
  'id' => 'section-one-under-tab-one',
268
- 'title' => __( 'Section One', SAP_TEXTDOMAIN ),
269
- 'description' => __( 'This section includes some settings for you to configure.', SAP_TEXTDOMAIN ),
270
  'tab' => 'tab-one',
271
  )
272
  );
@@ -327,8 +330,8 @@ $sap->add_setting(
327
  $type,
328
  array(
329
  'id' => 'my-first-setting',
330
- 'title' => __( 'My First Setting', SAP_TEXTDOMAIN ),
331
- 'description' => __( 'A demonstration of my first setting', SAP_TEXTDOMAIN );
332
  ...
333
  )
334
  );
@@ -368,6 +371,18 @@ $all_page_settings[ $my_setting_id ];
368
 
369
  ## Changelog
370
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  - 2.0.a.5 - 2014-05-15
372
  - Fix a bug with the Textarea component callback
373
 
19
 
20
  - Text field
21
  - Textarea field
22
+ - Toggle (checkbox to enable/disable setting)
23
  - Select dropdown with custom options
24
  - Select dropdown of any post type
25
  - Select dropdown of any taxonomy type
26
  - HTML Content (for instructions, links or other inert text)
27
+ - WordPress Editor
28
 
29
  ## Controls Supported for Special Use Cases
30
 
31
+ - Date and Time Scheduler
32
+ - Google Map Address (with GeoLocation)
33
  - Business Opening Hours
34
 
35
  ## Usage
41
  require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
42
  $sap = sap_initialize_library(
43
  array(
44
+ 'version' => '2.0.a.8', // Version of the library
45
  'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
46
  )
47
  );
51
  'options', // Admin menu which this page should be added to
52
  array( // Array of key/value pairs matching the AdminPage class constructor variables
53
  'id' => 'basic-settings',
54
+ 'title' => __( 'Page Title', 'textdomain' ),
55
+ 'menu_title' => __( 'menu Title', 'textdomain' ),
56
  'description' => '',
57
  'capability' => 'manage_options' // User permissions access level
58
  )
63
  'basic-settings', // Page to add this section to
64
  array( // Array of key/value pairs matching the AdminPageSection class constructor variables
65
  'id' => 'basic-details',
66
+ 'title' => __( 'Basic Details', 'textdomain' ),
67
+ 'description' => __( 'This section includes some basic details for you to configure.', 'textdomain' )
68
  )
69
  );
70
 
75
  'select', // Type of setting (see sapLibrary::get_setting_classname()
76
  array(
77
  'id' => 'select-field',
78
+ 'title' => __( 'Select Field', 'textdomain' ),
79
+ 'description' => __( 'A demonstration of the select field type.', 'textdomain' ),
80
  'options' => array(
81
+ 'one' => __( 'Option 1', 'textdomain' ),
82
+ 'two' => __( 'Option 2', 'textdomain' ),
83
+ 'three' => __( 'Option 3', 'textdomain' )
84
  )
85
  )
86
  );
130
  require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
131
  $sap = sap_initialize_library(
132
  $args = array(
133
+ 'version' => '2.0.a.8', // Version of the library
134
  'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
135
  )
136
  );
187
  $type,
188
  $args = array(
189
  'id' => 'my-settings',
190
+ 'title' => __( 'Page Title', 'textdomain' ),
191
+ 'menu_title' => __( 'menu Title', 'textdomain' ),
192
  'description' => '',
193
  'capability' => 'manage_options'
194
  'default_tab' => 'tab-one',
240
  $page_id,
241
  $args = array(
242
  'id' => 'basic-details-section',
243
+ 'title' => __( 'Basic Details', 'textdomain' ),
244
+ 'description' => __( 'This section includes some basic details for you to configure.', 'textdomain' )
245
  )
246
  );
247
  ```
255
  $page_id,
256
  $args = array(
257
  'id' => 'tab-one',
258
+ 'title' => __( 'Tab One', 'textdomain' ),
259
+ 'description' => __( 'This tab includes some settings for you to configure.', 'textdomain' ),
260
  'is_tab' => true,
261
  )
262
  );
268
  $page_id,
269
  $args = array(
270
  'id' => 'section-one-under-tab-one',
271
+ 'title' => __( 'Section One', 'textdomain' ),
272
+ 'description' => __( 'This section includes some settings for you to configure.', 'textdomain' ),
273
  'tab' => 'tab-one',
274
  )
275
  );
330
  $type,
331
  array(
332
  'id' => 'my-first-setting',
333
+ 'title' => __( 'My First Setting', 'textdomain' ),
334
+ 'description' => __( 'A demonstration of my first setting', 'textdomain' );
335
  ...
336
  )
337
  );
371
 
372
  ## Changelog
373
 
374
+ - 2_0_a_8 - 2014-11-12
375
+ - SelectPost: Use WP_Query instead of get_posts() so that filters can effect the list
376
+ - Require translateable strings to be declared when adding the setting so the library can conform to the upcoming single textdomain best practice in the .org repos
377
+
378
+ - 2_0_a_7 - 2014-08-20
379
+ - Only enqueue assets on appropriate admin pages to prevent version conflicts and be a good citizen
380
+ - Enforce stored date/time formats so date format is reliable
381
+
382
+ - 2.0.a.6 - 2014-08-12
383
+ - Add Google Map Address component
384
+ - Custom settings loaded through the extension path should not use versions
385
+
386
  - 2.0.a.5 - 2014-05-15
387
  - Fix a bug with the Textarea component callback
388
 
lib/simple-admin-pages/classes/AdminPage.Menu.class.php CHANGED
@@ -8,7 +8,7 @@
8
  * @package Simple Admin Pages
9
  */
10
 
11
- class sapAdminPageMenu_2_0_a_7 extends sapAdminPage_2_0_a_7 {
12
 
13
  public $setup_function = 'add_menu_page'; // WP function to register the page
14
 
8
  * @package Simple Admin Pages
9
  */
10
 
11
+ class sapAdminPageMenu_2_0_a_8 extends sapAdminPage_2_0_a_8 {
12
 
13
  public $setup_function = 'add_menu_page'; // WP function to register the page
14
 
lib/simple-admin-pages/classes/AdminPage.Submenu.class.php CHANGED
@@ -8,7 +8,7 @@
8
  * @package Simple Admin Pages
9
  */
10
 
11
- class sapAdminPageSubmenu_2_0_a_7 extends sapAdminPage_2_0_a_7 {
12
 
13
  public $setup_function = 'add_submenu_page'; // WP function to register the page
14
 
8
  * @package Simple Admin Pages
9
  */
10
 
11
+ class sapAdminPageSubmenu_2_0_a_8 extends sapAdminPage_2_0_a_8 {
12
 
13
  public $setup_function = 'add_submenu_page'; // WP function to register the page
14
 
lib/simple-admin-pages/classes/AdminPage.Themes.class.php CHANGED
@@ -8,7 +8,7 @@
8
  * @package Simple Admin Pages
9
  */
10
 
11
- class sapAdminPageThemes_2_0_a_7 extends sapAdminPage_2_0_a_7 {
12
 
13
  public $setup_function = 'add_theme_page'; // WP function to register the page
14
 
8
  * @package Simple Admin Pages
9
  */
10
 
11
+ class sapAdminPageThemes_2_0_a_8 extends sapAdminPage_2_0_a_8 {
12
 
13
  public $setup_function = 'add_theme_page'; // WP function to register the page
14
 
lib/simple-admin-pages/classes/AdminPage.class.php CHANGED
@@ -7,7 +7,7 @@
7
  * @package Simple Admin Pages
8
  */
9
 
10
- class sapAdminPage_2_0_a_7 {
11
 
12
  public $title;
13
  public $menu_title;
7
  * @package Simple Admin Pages
8
  */
9
 
10
+ class sapAdminPage_2_0_a_8 {
11
 
12
  public $title;
13
  public $menu_title;
lib/simple-admin-pages/classes/AdminPageSection.class.php CHANGED
@@ -7,7 +7,7 @@
7
  * @package Simple Admin Pages
8
  */
9
 
10
- class sapAdminPageSection_2_0_a_7 {
11
 
12
  // Page defaults
13
  public $id; // unique id for this section
7
  * @package Simple Admin Pages
8
  */
9
 
10
+ class sapAdminPageSection_2_0_a_8 {
11
 
12
  // Page defaults
13
  public $id; // unique id for this section
lib/simple-admin-pages/classes/AdminPageSetting.Address.class.php CHANGED
@@ -7,7 +7,7 @@
7
  * @package Simple Admin Pages
8
  */
9
 
10
- class sapAdminPageSettingAddress_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
11
 
12
  /*
13
  * Size of this textarea
@@ -33,6 +33,27 @@ class sapAdminPageSettingAddress_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
33
 
34
  public $sanitize_callback = 'sanitize_text_field';
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  /**
37
  * Escape the value to display it safely HTML textarea fields
38
  * @since 2.0.a.5
@@ -77,28 +98,12 @@ class sapAdminPageSettingAddress_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
77
  * @since 2.0.a.5
78
  */
79
  public function display_setting() {
80
-
81
- $strings = array(
82
- 'sep-lat-lon' => _x( ', ', 'separates latitude and longitude', SAP_TEXTDOMAIN ),
83
- 'no-setting' => __( 'No map coordinates set.', SAP_TEXTDOMAIN ),
84
- 'retrieving' => __( 'Requesting new coordinates', SAP_TEXTDOMAIN ),
85
- 'select' => __( 'Select a match below', SAP_TEXTDOMAIN ),
86
- 'view' => __( 'View', SAP_TEXTDOMAIN ),
87
- 'retrieve' => __( 'Retrieve map coordinates', SAP_TEXTDOMAIN ),
88
- 'remove' => __( 'Remove map coordinates', SAP_TEXTDOMAIN ),
89
- 'try_again' => __( 'Try again?', SAP_TEXTDOMAIN ),
90
- 'result_error' => __( 'Error', SAP_TEXTDOMAIN ),
91
- 'result_invalid' => __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', SAP_TEXTDOMAIN ),
92
- 'result_denied' => __( 'Request denied.', SAP_TEXTDOMAIN ),
93
- 'result_limit' => __( 'Request denied because you are over your request quota.', SAP_TEXTDOMAIN ),
94
- 'result_empty' => __( 'Nothing was found at that address', SAP_TEXTDOMAIN ),
95
- );
96
 
97
  wp_localize_script(
98
  'sap-address',
99
  'sap_address',
100
  array(
101
- 'strings' => $strings,
102
  )
103
  );
104
 
@@ -112,20 +117,20 @@ class sapAdminPageSettingAddress_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
112
  <span class="dashicons dashicons-location-alt"></span>
113
  <span class="sap-map-coords">
114
  <?php if ( empty( $this->value['lat'] ) || empty( $this->value['lon'] ) ) : ?>
115
- <?php echo $strings['no-setting']; ?>
116
  <?php else : ?>
117
- <?php echo $this->value['lat'] . $strings['sep-lat-lon'] . $this->value['lon']; ?>
118
- <a href="//maps.google.com/maps?q=<?php echo esc_attr( $this->value['lat'] ) . ',' . esc_attr( $this->value['lon'] ); ?>" class="sap-view-coords" target="_blank"><?php echo $strings['view']; ?></a>
119
  <?php endif; ?>
120
  </span>
121
  </p>
122
  <p class="sap-coords-action-wrapper">
123
  <a href="#" class="sap-get-coords">
124
- <?php echo $strings['retrieve']; ?>
125
  </a>
126
- <?php _ex( ' | ', 'separator between admin action links in address component', SAP_TEXTDOMAIN ); ?>
127
  <a href="#" class="sap-remove-coords">
128
- <?php echo $strings['remove']; ?>
129
  </a>
130
  </p>
131
  <input type="hidden" class="lat" name="<?php echo $this->get_input_name(); ?>[lat]" value="<?php echo $this->value['lat']; ?>">
7
  * @package Simple Admin Pages
8
  */
9
 
10
+ class sapAdminPageSettingAddress_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
11
 
12
  /*
13
  * Size of this textarea
33
 
34
  public $sanitize_callback = 'sanitize_text_field';
35
 
36
+ /**
37
+ * Translateable strings required for this component
38
+ * @since 2.0.a.8
39
+ */
40
+ public $strings = array(
41
+ 'sep-action-links' => null, // _x( ' | ', 'separator between admin action links in address component', 'textdomain' ),
42
+ 'sep-lat-lon' => null, // _x( ', ', 'separates latitude and longitude', 'textdomain' ),
43
+ 'no-setting' => null, // __( 'No map coordinates set.', 'textdomain' ),
44
+ 'retrieving' => null, // __( 'Requesting new coordinates', 'textdomain' ),
45
+ 'select' => null, // __( 'Select a match below', 'textdomain' ),
46
+ 'view' => null, // __( 'View', 'textdomain' ),
47
+ 'retrieve' => null, // __( 'Retrieve map coordinates', 'textdomain' ),
48
+ 'remove' => null, // __( 'Remove map coordinates', 'textdomain' ),
49
+ 'try_again' => null, // __( 'Try again?', 'textdomain' ),
50
+ 'result_error' => null, // __( 'Error', 'textdomain' ),
51
+ 'result_invalid' => null, // __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', 'textdomain' ),
52
+ 'result_denied' => null, // __( 'Request denied.', 'textdomain' ),
53
+ 'result_limit' => null, // __( 'Request denied because you are over your request quota.', 'textdomain' ),
54
+ 'result_empty' => null, // __( 'Nothing was found at that address', 'textdomain' ),
55
+ );
56
+
57
  /**
58
  * Escape the value to display it safely HTML textarea fields
59
  * @since 2.0.a.5
98
  * @since 2.0.a.5
99
  */
100
  public function display_setting() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  wp_localize_script(
103
  'sap-address',
104
  'sap_address',
105
  array(
106
+ 'strings' => $this->strings,
107
  )
108
  );
109
 
117
  <span class="dashicons dashicons-location-alt"></span>
118
  <span class="sap-map-coords">
119
  <?php if ( empty( $this->value['lat'] ) || empty( $this->value['lon'] ) ) : ?>
120
+ <?php echo $this->strings['no-setting']; ?>
121
  <?php else : ?>
122
+ <?php echo $this->value['lat'] . $this->strings['sep-lat-lon'] . $this->value['lon']; ?>
123
+ <a href="//maps.google.com/maps?q=<?php echo esc_attr( $this->value['lat'] ) . ',' . esc_attr( $this->value['lon'] ); ?>" class="sap-view-coords" target="_blank"><?php echo $this->strings['view']; ?></a>
124
  <?php endif; ?>
125
  </span>
126
  </p>
127
  <p class="sap-coords-action-wrapper">
128
  <a href="#" class="sap-get-coords">
129
+ <?php echo $this->strings['retrieve']; ?>
130
  </a>
131
+ <?php echo $this->strings['sep-action-links']; ?>
132
  <a href="#" class="sap-remove-coords">
133
+ <?php echo $this->strings['remove']; ?>
134
  </a>
135
  </p>
136
  <input type="hidden" class="lat" name="<?php echo $this->get_input_name(); ?>[lat]" value="<?php echo $this->value['lat']; ?>">
lib/simple-admin-pages/classes/AdminPageSetting.Editor.class.php CHANGED
@@ -7,7 +7,7 @@
7
  * @package Simple Admin Pages
8
  */
9
 
10
- class sapAdminPageSettingEditor_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
11
 
12
  public $sanitize_callback = 'wp_kses_post';
13
 
7
  * @package Simple Admin Pages
8
  */
9
 
10
+ class sapAdminPageSettingEditor_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
11
 
12
  public $sanitize_callback = 'wp_kses_post';
13
 
lib/simple-admin-pages/classes/AdminPageSetting.HTML.class.php CHANGED
@@ -14,7 +14,7 @@
14
  * @package Simple Admin Pages
15
  */
16
 
17
- class sapAdminPageSettingHTML_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
18
 
19
  public $sanitize_callback = 'sanitize_text_field';
20
 
14
  * @package Simple Admin Pages
15
  */
16
 
17
+ class sapAdminPageSettingHTML_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
18
 
19
  public $sanitize_callback = 'sanitize_text_field';
20
 
lib/simple-admin-pages/classes/AdminPageSetting.OpeningHours.class.php CHANGED
@@ -25,7 +25,7 @@
25
  * @package Simple Admin Pages
26
  */
27
 
28
- class sapAdminPageSettingOpeningHours_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
29
 
30
  public $sanitize_callback = 'sanitize_text_field';
31
 
25
  * @package Simple Admin Pages
26
  */
27
 
28
+ class sapAdminPageSettingOpeningHours_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
29
 
30
  public $sanitize_callback = 'sanitize_text_field';
31
 
lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php CHANGED
@@ -10,7 +10,7 @@
10
  * @package Simple Admin Pages
11
  */
12
 
13
- class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
14
 
15
  public $sanitize_callback = 'sanitize_text_field';
16
 
@@ -46,7 +46,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
46
  'sap-scheduler' => array(
47
  'path' => 'js/scheduler.js',
48
  'dependencies' => array( 'jquery' ),
49
- 'version' => '2.0.a.5',
50
  'footer' => true,
51
  ),
52
  // @todo there should be some way to load alternate language .js files
@@ -78,6 +78,9 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
78
  ),
79
  );
80
 
 
 
 
81
  public $weekdays = array(
82
  'monday' => 'Mo',
83
  'tuesday' => 'Tu',
@@ -88,6 +91,9 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
88
  'sunday' => 'Su',
89
  );
90
 
 
 
 
91
  public $weeks = array(
92
  'first' => '1st',
93
  'second' => '2nd',
@@ -96,6 +102,36 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
96
  'last' => 'last',
97
  );
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  /**
100
  * Number of minutes between time selection intervals
101
  */
@@ -138,13 +174,6 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
138
  */
139
  public $disable_end_time = false;
140
 
141
- /**
142
- * Array containing strings for schedule summaries. See the default
143
- * summaries at set_schedule_summaries(). Use this to overwrite the defaults
144
- * with anything more useful to this instance.
145
- */
146
- public $instance_schedule_summaries;
147
-
148
  /**
149
  * Escape the value to display it in text fields and other input fields
150
  * @since 2.0
@@ -263,7 +292,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
263
  </div>
264
  <div class="sap-add-scheduler">
265
  <a href="#" class="button">
266
- <?php _e( 'Add new scheduling rule', SAP_TEXTDOMAIN ); ?>
267
  </a>
268
  </div>
269
 
@@ -290,11 +319,11 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
290
  <li>
291
  <div class="dashicons dashicons-calendar"></div>
292
  <?php if ( $date_format == 'weekly' ) : ?>
293
- <?php _ex( 'Weekly', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
294
  <?php elseif ( $date_format == 'monthly' ) : ?>
295
- <?php _ex( 'Monthly', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
296
  <?php elseif ( $date_format == 'date' ) : ?>
297
- <?php _ex( 'Date', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
298
  <?php endif; ?>
299
  </li>
300
  <?php else : ?>
@@ -303,7 +332,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
303
  <li>
304
  <div class="dashicons dashicons-calendar"></div>
305
  <a href="#" data-format="weekly"<?php echo $date_format == 'weekly' ? ' class="selected"' : ''; ?>>
306
- <?php _ex( 'Weekly', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
307
  </a>
308
  </li>
309
  <?php endif; ?>
@@ -311,7 +340,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
311
  <?php if ( $this->disable_weeks === false ) : ?>
312
  <li>
313
  <a href="#" data-format="monthly"<?php echo $date_format == 'monthly' ? ' class="selected"' : ''; ?>>
314
- <?php _ex( 'Monthly', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
315
  </a>
316
  </li>
317
  <?php endif; ?>
@@ -319,7 +348,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
319
  <?php if ( $this->disable_date === false ) : ?>
320
  <li>
321
  <a href="#" data-format="date"<?php echo $date_format == 'date' ? ' class="selected"' : ''; ?>>
322
- <?php _ex( 'Date', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
323
  </a>
324
  </li>
325
  <?php endif; ?>
@@ -330,7 +359,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
330
  <?php if ( $this->disable_weekdays === false ) : ?>
331
  <ul class="sap-scheduler-weekdays">
332
  <li class="label">
333
- <?php _ex( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', SAP_TEXTDOMAIN ); ?>
334
  </li>
335
  <?php
336
  foreach ( $this->weekdays as $slug => $label ) :
@@ -346,7 +375,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
346
  <?php if ( $this->disable_weeks === false ) : ?>
347
  <ul class="sap-scheduler-weeks">
348
  <li class="label">
349
- <?php _ex( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', SAP_TEXTDOMAIN ); ?>
350
  </li>
351
  <?php
352
  foreach ( $this->weeks as $slug => $label ) :
@@ -362,7 +391,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
362
  <?php if ( $this->disable_date === false ) : ?>
363
  <div class="sap-scheduler-date-input">
364
  <label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]">
365
- <?php _e( 'Date', SAP_TEXTDOMAIN ); ?>
366
  </label>
367
  <input type="text" name="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" id="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" value="<?php echo empty( $values['date'] ) ? '' : $values['date']; ?>">
368
  </div>
@@ -377,12 +406,12 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
377
  <li>
378
  <div class="dashicons dashicons-clock"></div>
379
  <a href="#" data-format="time-slot"<?php echo $time_format == 'time-slot' ? ' class="selected"' : ''; ?>>
380
- <?php _ex( 'Time', 'Label to select time slot for a scheduling rule', SAP_TEXTDOMAIN ); ?>
381
  </a>
382
  </li>
383
  <li>
384
  <a href="#" data-format="all-day"<?php echo $time_format == 'all-day' ? ' class="selected"' : ''; ?>>
385
- <?php _ex( 'All day', 'Label to set a scheduling rule to last all day', SAP_TEXTDOMAIN ); ?>
386
  </a>
387
  </li>
388
  </ul>
@@ -391,7 +420,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
391
 
392
  <div class="start">
393
  <label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][start]">
394
- <?php _ex( 'Start', 'Label for the starting time of a scheduling rule', SAP_TEXTDOMAIN ); ?>
395
  </label>
396
  <input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" value="<?php echo empty( $values['time']['start'] ) ? '' : $values['time']['start']; ?>">
397
  </div>
@@ -399,7 +428,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
399
  <?php if ( $this->disable_end_time === false ) : ?>
400
  <div class="end">
401
  <label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][end]">
402
- <?php _ex( 'End', 'Label for the ending time of a scheduling rule', SAP_TEXTDOMAIN ); ?>
403
  </label>
404
  <input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" value="<?php echo empty( $values['time']['end'] ) ? '' : $values['time']['end']; ?>">
405
  </div>
@@ -408,7 +437,7 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
408
  </div>
409
 
410
  <div class="sap-scheduler-all-day">
411
- <?php _ex( 'All day long. Want to <a href="#" data-format="time-slot">set a time slot</a>?', 'Prompt displayed when a scheduling rule is set without any time restrictions.', SAP_TEXTDOMAIN ); ?>
412
  </div>
413
 
414
  </div>
@@ -427,16 +456,16 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
427
  <?php endif; ?>
428
  </div>
429
  <div class="sap-scheduler-control">
430
- <a href="#" class="toggle" title="<?php _e( 'Open and close this rule', SAP_TEXTDOMAIN ); ?>">
431
  <div class="dashicons dashicons-<?php echo $list ? 'edit' : 'arrow-up-alt2'; ?>"></div>
432
  <span class="screen-reader-text">
433
- <?php _e( 'Open and close this rule', SAP_TEXTDOMAIN ); ?>
434
  </span>
435
  </a>
436
- <a href="#" class="delete" title="<?php _e( 'Delete rule', SAP_TEXTDOMAIN ); ?>">
437
  <div class="dashicons dashicons-dismiss"></div>
438
  <span class="screen-reader-text">
439
- <?php _e( 'Delete scheduling rule', SAP_TEXTDOMAIN ); ?>
440
  </span>
441
  </a>
442
  </div>
@@ -520,19 +549,15 @@ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
520
  }
521
 
522
  $this->schedule_summaries = array(
523
- 'never' => _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule.', SAP_TEXTDOMAIN ),
524
- 'weekly_always' => _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule.', SAP_TEXTDOMAIN ),
525
- 'monthly_weekdays' => _x( '{days} on the {weeks} week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. The {days} and {weeks} bits should be left alone and will be replaced by a comma-separated list of days (the first one) and weeks (the second one) in the following format: M, T, W on the first, second week of the month', SAP_TEXTDOMAIN ),
526
- 'monthly_weeks' => _x( '{weeks} week of the month', 'Brief description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. {weeks} should be left alone and will be replaced by a comma-separated list of weeks (the second one) in the following format: First, second week of the month', SAP_TEXTDOMAIN ),
527
- 'all_day' => _x( 'All day', 'Brief default description of a scheduling rule when no times are set', SAP_TEXTDOMAIN ),
528
- 'before' => _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm.', SAP_TEXTDOMAIN ),
529
- 'after' => _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm.', SAP_TEXTDOMAIN ),
530
- 'separator' => _x( '&mdash;', 'Default separator between times of a scheduling rule.', SAP_TEXTDOMAIN ),
531
  );
532
-
533
- if ( !empty( $this->instance_schedule_summaries ) ) {
534
- $this->schedule_summaries = array_merge( $this->schedule_summaries, $this->instance_schedule_summaries );
535
- }
536
  }
537
 
538
  /**
10
  * @package Simple Admin Pages
11
  */
12
 
13
+ class sapAdminPageSettingScheduler_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
14
 
15
  public $sanitize_callback = 'sanitize_text_field';
16
 
46
  'sap-scheduler' => array(
47
  'path' => 'js/scheduler.js',
48
  'dependencies' => array( 'jquery' ),
49
+ 'version' => '2.0.a.8',
50
  'footer' => true,
51
  ),
52
  // @todo there should be some way to load alternate language .js files
78
  ),
79
  );
80
 
81
+ /**
82
+ * Used for data storage. Not translated
83
+ */
84
  public $weekdays = array(
85
  'monday' => 'Mo',
86
  'tuesday' => 'Tu',
91
  'sunday' => 'Su',
92
  );
93
 
94
+ /**
95
+ * Used for data storage. Not translated
96
+ */
97
  public $weeks = array(
98
  'first' => '1st',
99
  'second' => '2nd',
102
  'last' => 'last',
103
  );
104
 
105
+ /**
106
+ * Translateable strings required for this component
107
+ * @since 2.0.a.8
108
+ */
109
+ public $strings = array(
110
+ 'add_rule' => null, // __( 'Add new scheduling rule', 'textdomain' ),
111
+ 'weekly' => null, // _x( 'Weekly', 'Format of a scheduling rule', 'textdomain' ),
112
+ 'monthly' => null, // _x( 'Monthly', 'Format of a scheduling rule', 'textdomain' ),
113
+ 'date' => null, // _x( 'Date', 'Format of a scheduling rule', 'textdomain' ),
114
+ 'weekdays' => null, // _x( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', 'textdomain' ),
115
+ 'month_weeks' => null, // _x( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', 'textdomain' ),
116
+ 'date_label' => null, // _x( 'Date', 'Label to select a date for a scheduling rule', 'textdomain' ),
117
+ 'time_label' => null, // _x( 'Time', 'Label to select a time slot for a scheduling rule', 'textdomain' ),
118
+ 'allday' => null, // _x( 'All day', 'Label to set a scheduling rule to last all day', 'textdomain' ),
119
+ 'start' => null, // _x( 'Start', 'Label for the starting time of a scheduling rule', 'textdomain' ),
120
+ 'end' => null, // _x( 'End', 'Label for the ending time of a scheduling rule', 'textdomain' ),
121
+ 'set_time_prompt' => null, // _x( 'All day long. Want to %sset a time slot%s?', 'Prompt displayed when a scheduling rule is set without any time restrictions', 'textdomain' ),
122
+ 'toggle' => null, // _x( 'Open and close this rule', 'Toggle a scheduling rule open and closed', 'textdomain' ),
123
+ 'delete' => null, // _x( 'Delete rule', 'Delete a scheduling rule', 'textdomain' ),
124
+ 'delete_schedule' => null, // __( 'Delete scheduling rule', 'textdomain' ),
125
+ 'never' => null, // _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'textdomain' ),
126
+ 'weekly_always' => null, // _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'textdomain' ),
127
+ 'monthly_weekdays' => null, // _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'textdomain' ),
128
+ 'monthly_weeks' => null, // _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'textdomain' ),
129
+ 'all_day' => null, // _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'textdomain' ),
130
+ 'before' => null, // _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm', 'textdomain' ),
131
+ 'after' => null, // _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm', 'textdomain' ),
132
+ 'separator' => null, // _x( '&mdash;', 'Separator between times of a scheduling rule', 'textdomain' ),
133
+ );
134
+
135
  /**
136
  * Number of minutes between time selection intervals
137
  */
174
  */
175
  public $disable_end_time = false;
176
 
 
 
 
 
 
 
 
177
  /**
178
  * Escape the value to display it in text fields and other input fields
179
  * @since 2.0
292
  </div>
293
  <div class="sap-add-scheduler">
294
  <a href="#" class="button">
295
+ <?php echo $this->strings['add_rule']; ?>
296
  </a>
297
  </div>
298
 
319
  <li>
320
  <div class="dashicons dashicons-calendar"></div>
321
  <?php if ( $date_format == 'weekly' ) : ?>
322
+ <?php echo $this->strings['weekly']; ?>
323
  <?php elseif ( $date_format == 'monthly' ) : ?>
324
+ <?php echo $this->strings['monthly']; ?>
325
  <?php elseif ( $date_format == 'date' ) : ?>
326
+ <?php echo $this->strings['date']; ?>
327
  <?php endif; ?>
328
  </li>
329
  <?php else : ?>
332
  <li>
333
  <div class="dashicons dashicons-calendar"></div>
334
  <a href="#" data-format="weekly"<?php echo $date_format == 'weekly' ? ' class="selected"' : ''; ?>>
335
+ <?php echo $this->strings['weekly']; ?>
336
  </a>
337
  </li>
338
  <?php endif; ?>
340
  <?php if ( $this->disable_weeks === false ) : ?>
341
  <li>
342
  <a href="#" data-format="monthly"<?php echo $date_format == 'monthly' ? ' class="selected"' : ''; ?>>
343
+ <?php echo $this->strings['monthly']; ?>
344
  </a>
345
  </li>
346
  <?php endif; ?>
348
  <?php if ( $this->disable_date === false ) : ?>
349
  <li>
350
  <a href="#" data-format="date"<?php echo $date_format == 'date' ? ' class="selected"' : ''; ?>>
351
+ <?php echo $this->strings['date']; ?>
352
  </a>
353
  </li>
354
  <?php endif; ?>
359
  <?php if ( $this->disable_weekdays === false ) : ?>
360
  <ul class="sap-scheduler-weekdays">
361
  <li class="label">
362
+ <?php echo $this->strings['weekdays']; ?>
363
  </li>
364
  <?php
365
  foreach ( $this->weekdays as $slug => $label ) :
375
  <?php if ( $this->disable_weeks === false ) : ?>
376
  <ul class="sap-scheduler-weeks">
377
  <li class="label">
378
+ <?php echo $this->strings['month_weeks']; ?>
379
  </li>
380
  <?php
381
  foreach ( $this->weeks as $slug => $label ) :
391
  <?php if ( $this->disable_date === false ) : ?>
392
  <div class="sap-scheduler-date-input">
393
  <label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]">
394
+ <?php echo $this->strings['date_label']; ?>
395
  </label>
396
  <input type="text" name="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" id="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" value="<?php echo empty( $values['date'] ) ? '' : $values['date']; ?>">
397
  </div>
406
  <li>
407
  <div class="dashicons dashicons-clock"></div>
408
  <a href="#" data-format="time-slot"<?php echo $time_format == 'time-slot' ? ' class="selected"' : ''; ?>>
409
+ <?php echo $this->strings['time_label']; ?>
410
  </a>
411
  </li>
412
  <li>
413
  <a href="#" data-format="all-day"<?php echo $time_format == 'all-day' ? ' class="selected"' : ''; ?>>
414
+ <?php echo $this->strings['allday']; ?>
415
  </a>
416
  </li>
417
  </ul>
420
 
421
  <div class="start">
422
  <label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][start]">
423
+ <?php echo $this->strings['start']; ?>
424
  </label>
425
  <input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" value="<?php echo empty( $values['time']['start'] ) ? '' : $values['time']['start']; ?>">
426
  </div>
428
  <?php if ( $this->disable_end_time === false ) : ?>
429
  <div class="end">
430
  <label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][end]">
431
+ <?php echo $this->strings['end']; ?>
432
  </label>
433
  <input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" value="<?php echo empty( $values['time']['end'] ) ? '' : $values['time']['end']; ?>">
434
  </div>
437
  </div>
438
 
439
  <div class="sap-scheduler-all-day">
440
+ <?php printf( $this->strings['set_time_prompt'], '<a href="#" data-format="time-slot">', '</a>' ); ?>
441
  </div>
442
 
443
  </div>
456
  <?php endif; ?>
457
  </div>
458
  <div class="sap-scheduler-control">
459
+ <a href="#" class="toggle" title="<?php echo $this->strings['toggle']; ?>">
460
  <div class="dashicons dashicons-<?php echo $list ? 'edit' : 'arrow-up-alt2'; ?>"></div>
461
  <span class="screen-reader-text">
462
+ <?php echo $this->strings['toggle']; ?>
463
  </span>
464
  </a>
465
+ <a href="#" class="delete" title="<?php echo $this->strings['delete']; ?>">
466
  <div class="dashicons dashicons-dismiss"></div>
467
  <span class="screen-reader-text">
468
+ <?php echo $this->strings['delete_schedule']; ?>
469
  </span>
470
  </a>
471
  </div>
549
  }
550
 
551
  $this->schedule_summaries = array(
552
+ 'never' => $this->strings['never'],
553
+ 'weekly_always' => $this->strings['weekly_always'],
554
+ 'monthly_weekdays' => sprintf( $this->strings['monthly_weekdays'], '{days}', '{weeks}' ),
555
+ 'monthly_weeks' => sprintf( $this->strings['monthly_weeks'], '{weeks}' ),
556
+ 'all_day' => $this->strings['all_day'],
557
+ 'before' => $this->strings['before'],
558
+ 'after' => $this->strings['after'],
559
+ 'separator' => $this->strings['separator'],
560
  );
 
 
 
 
561
  }
562
 
563
  /**
lib/simple-admin-pages/classes/AdminPageSetting.Select.class.php CHANGED
@@ -21,7 +21,7 @@
21
  * @package Simple Admin Pages
22
  */
23
 
24
- class sapAdminPageSettingSelect_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
25
 
26
  public $sanitize_callback = 'sanitize_text_field';
27
 
21
  * @package Simple Admin Pages
22
  */
23
 
24
+ class sapAdminPageSettingSelect_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
25
 
26
  public $sanitize_callback = 'sanitize_text_field';
27
 
lib/simple-admin-pages/classes/AdminPageSetting.SelectPost.class.php CHANGED
@@ -17,7 +17,7 @@
17
  * @package Simple Admin Pages
18
  */
19
 
20
- class sapAdminPageSettingSelectPost_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
21
 
22
  public $sanitize_callback = 'intval';
23
 
@@ -36,7 +36,7 @@ class sapAdminPageSettingSelectPost_2_0_a_7 extends sapAdminPageSetting_2_0_a_7
36
  */
37
  public function display_setting() {
38
 
39
- $posts = get_posts( $this->args );
40
 
41
  ?>
42
 
@@ -46,14 +46,16 @@ class sapAdminPageSettingSelectPost_2_0_a_7 extends sapAdminPageSetting_2_0_a_7
46
  <option></option>
47
  <?php endif; ?>
48
 
49
- <?php foreach ( $posts as $post ) : ?>
50
- <option value="<?php echo esc_attr( $post->ID ); ?>"<?php if( $this->value == $post->ID ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $post->post_title ); ?></option>
51
- <?php endforeach; ?>
52
 
53
  </select>
54
 
55
  <?php
56
 
 
 
57
  $this->display_description();
58
 
59
  }
17
  * @package Simple Admin Pages
18
  */
19
 
20
+ class sapAdminPageSettingSelectPost_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
21
 
22
  public $sanitize_callback = 'intval';
23
 
36
  */
37
  public function display_setting() {
38
 
39
+ $posts = new WP_Query( $this->args );
40
 
41
  ?>
42
 
46
  <option></option>
47
  <?php endif; ?>
48
 
49
+ <?php while( $posts->have_posts() ) : $posts->next_post(); ?>
50
+ <option value="<?php echo absint( $posts->post->ID ); ?>" <?php selected( $this->value, $posts->post->ID ); ?>><?php echo esc_attr( $posts->post->post_title ); ?></option>
51
+ <?php endwhile; ?>
52
 
53
  </select>
54
 
55
  <?php
56
 
57
+ wp_reset_postdata();
58
+
59
  $this->display_description();
60
 
61
  }
lib/simple-admin-pages/classes/AdminPageSetting.SelectTaxonomy.class.php CHANGED
@@ -19,7 +19,7 @@
19
  * @package Simple Admin Pages
20
  */
21
 
22
- class sapAdminPageSettingSelectTaxonomy_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
23
 
24
  public $sanitize_callback = 'intval';
25
 
19
  * @package Simple Admin Pages
20
  */
21
 
22
+ class sapAdminPageSettingSelectTaxonomy_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
23
 
24
  public $sanitize_callback = 'intval';
25
 
lib/simple-admin-pages/classes/AdminPageSetting.Text.class.php CHANGED
@@ -7,7 +7,7 @@
7
  * @package Simple Admin Pages
8
  */
9
 
10
- class sapAdminPageSettingText_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
11
 
12
  public $sanitize_callback = 'sanitize_text_field';
13
 
7
  * @package Simple Admin Pages
8
  */
9
 
10
+ class sapAdminPageSettingText_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
11
 
12
  public $sanitize_callback = 'sanitize_text_field';
13
 
lib/simple-admin-pages/classes/AdminPageSetting.Textarea.class.php CHANGED
@@ -9,7 +9,7 @@
9
  * @todo textareas should have an option to swap new lines for <br>s
10
  */
11
 
12
- class sapAdminPageSettingTextarea_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
13
 
14
  /*
15
  * Size of this textarea
9
  * @todo textareas should have an option to swap new lines for <br>s
10
  */
11
 
12
+ class sapAdminPageSettingTextarea_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
13
 
14
  /*
15
  * Size of this textarea
lib/simple-admin-pages/classes/AdminPageSetting.Toggle.class.php CHANGED
@@ -17,7 +17,7 @@
17
  * @package Simple Admin Pages
18
  */
19
 
20
- class sapAdminPageSettingToggle_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
21
 
22
  public $sanitize_callback = 'sanitize_text_field';
23
 
17
  * @package Simple Admin Pages
18
  */
19
 
20
+ class sapAdminPageSettingToggle_2_0_a_8 extends sapAdminPageSetting_2_0_a_8 {
21
 
22
  public $sanitize_callback = 'sanitize_text_field';
23
 
lib/simple-admin-pages/classes/AdminPageSetting.class.php CHANGED
@@ -15,7 +15,7 @@
15
  * @package Simple Admin Pages
16
  */
17
 
18
- abstract class sapAdminPageSetting_2_0_a_7 {
19
 
20
  // Page defaults
21
  public $id; // used in form fields and database to track and store setting
@@ -72,6 +72,23 @@ abstract class sapAdminPageSetting_2_0_a_7 {
72
  */
73
  );
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  /**
76
  * Initialize the setting
77
  *
@@ -88,10 +105,8 @@ abstract class sapAdminPageSetting_2_0_a_7 {
88
  // Get any existing value
89
  $this->set_value();
90
 
91
- // Set an error if the object is missing necessary data
92
- if ( $this->missing_data() ) {
93
- $this->set_error();
94
- }
95
  }
96
 
97
  /**
@@ -117,7 +132,7 @@ abstract class sapAdminPageSetting_2_0_a_7 {
117
  * Check for missing data when setup.
118
  * @since 1.0
119
  */
120
- private function missing_data( ) {
121
 
122
  $error_type = 'missing_data';
123
 
@@ -138,6 +153,19 @@ abstract class sapAdminPageSetting_2_0_a_7 {
138
  )
139
  );
140
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  }
142
 
143
  /**
15
  * @package Simple Admin Pages
16
  */
17
 
18
+ abstract class sapAdminPageSetting_2_0_a_8 {
19
 
20
  // Page defaults
21
  public $id; // used in form fields and database to track and store setting
72
  */
73
  );
74
 
75
+ /**
76
+ * Translateable strings required for this component
77
+ *
78
+ * Settings classes which require translateable strings should be
79
+ * defined with string id's pointing to null values. The actual
80
+ * strings should be passed with the $sap->add_setting() call.
81
+ *
82
+ * @since 2.0.a.8
83
+ */
84
+ public $strings = array(
85
+ /**
86
+ * Example
87
+ *
88
+ 'string_id' => null
89
+ */
90
+ );
91
+
92
  /**
93
  * Initialize the setting
94
  *
105
  // Get any existing value
106
  $this->set_value();
107
 
108
+ // Check for missing data
109
+ $this->missing_data();
 
 
110
  }
111
 
112
  /**
132
  * Check for missing data when setup.
133
  * @since 1.0
134
  */
135
+ private function missing_data() {
136
 
137
  $error_type = 'missing_data';
138
 
153
  )
154
  );
155
  }
156
+
157
+ // Check for strings
158
+ foreach ( $this->strings as $id => $string ) {
159
+
160
+ if ( $string === null ) {
161
+ $this->set_error(
162
+ array(
163
+ 'type' => $error_type,
164
+ 'data' => 'string: ' . $id,
165
+ )
166
+ );
167
+ }
168
+ }
169
  }
170
 
171
  /**
lib/simple-admin-pages/classes/Library.class.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists( 'sapLibrary_2_0_a_7' ) ) {
3
  /**
4
  * This library class loads and provides access to the correct version of the
5
  * Simple Admin Pages library.
@@ -7,10 +7,10 @@ if ( !class_exists( 'sapLibrary_2_0_a_7' ) ) {
7
  * @since 1.0
8
  * @package Simple Admin Pages
9
  */
10
- class sapLibrary_2_0_a_7 {
11
 
12
  // Version of the library
13
- private $version = '2.0.a.7';
14
 
15
  // A full URL to the library which is used to correctly link scripts and
16
  // stylesheets.
1
  <?php
2
+ if ( !class_exists( 'sapLibrary_2_0_a_8' ) ) {
3
  /**
4
  * This library class loads and provides access to the correct version of the
5
  * Simple Admin Pages library.
7
  * @since 1.0
8
  * @package Simple Admin Pages
9
  */
10
+ class sapLibrary_2_0_a_8 {
11
 
12
  // Version of the library
13
+ private $version = '2.0.a.8';
14
 
15
  // A full URL to the library which is used to correctly link scripts and
16
  // stylesheets.
lib/simple-admin-pages/lib/pickadate/legacy.js CHANGED
@@ -1,10 +1,133 @@
 
 
 
 
 
 
 
 
 
 
1
  /*!
2
  * Legacy browser support
3
  */
4
- [].map||(Array.prototype.map=function(a,b){for(var c=this,d=c.length,e=new Array(d),f=0;d>f;f++)f in c&&(e[f]=a.call(b,c[f],f,c));return e}),[].filter||(Array.prototype.filter=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=arguments[1],f=0;c>f;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g)}return d}),[].indexOf||(Array.prototype.indexOf=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!==d&&1/0!=d&&d!=-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1});/*!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  * Cross-Browser Split 1.1.1
6
  * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
7
  * Available under the MIT License
8
  * http://blog.stevenlevithan.com/archives/cross-browser-split
9
  */
10
- var nativeSplit=String.prototype.split,compliantExecNpcg=void 0===/()??/.exec("")[1];String.prototype.split=function(a,b){var c=this;if("[object RegExp]"!==Object.prototype.toString.call(a))return nativeSplit.call(c,a,b);var d,e,f,g,h=[],i=(a.ignoreCase?"i":"")+(a.multiline?"m":"")+(a.extended?"x":"")+(a.sticky?"y":""),j=0;for(a=new RegExp(a.source,i+"g"),c+="",compliantExecNpcg||(d=new RegExp("^"+a.source+"$(?!\\s)",i)),b=void 0===b?-1>>>0:b>>>0;(e=a.exec(c))&&(f=e.index+e[0].length,!(f>j&&(h.push(c.slice(j,e.index)),!compliantExecNpcg&&e.length>1&&e[0].replace(d,function(){for(var a=1;a<arguments.length-2;a++)void 0===arguments[a]&&(e[a]=void 0)}),e.length>1&&e.index<c.length&&Array.prototype.push.apply(h,e.slice(1)),g=e[0].length,j=f,h.length>=b)));)a.lastIndex===e.index&&a.lastIndex++;return j===c.length?(g||!a.test(""))&&h.push(""):h.push(c.slice(j)),h.length>b?h.slice(0,b):h};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ /*jshint
3
+ asi: true,
4
+ unused: true,
5
+ boss: true,
6
+ loopfunc: true,
7
+ eqnull: true
8
+ */
9
+
10
+
11
  /*!
12
  * Legacy browser support
13
  */
14
+
15
+
16
+ // Map array support
17
+ if ( ![].map ) {
18
+ Array.prototype.map = function ( callback, self ) {
19
+ var array = this, len = array.length, newArray = new Array( len )
20
+ for ( var i = 0; i < len; i++ ) {
21
+ if ( i in array ) {
22
+ newArray[ i ] = callback.call( self, array[ i ], i, array )
23
+ }
24
+ }
25
+ return newArray
26
+ }
27
+ }
28
+
29
+
30
+ // Filter array support
31
+ if ( ![].filter ) {
32
+ Array.prototype.filter = function( callback ) {
33
+ if ( this == null ) throw new TypeError()
34
+ var t = Object( this ), len = t.length >>> 0
35
+ if ( typeof callback != 'function' ) throw new TypeError()
36
+ var newArray = [], thisp = arguments[ 1 ]
37
+ for ( var i = 0; i < len; i++ ) {
38
+ if ( i in t ) {
39
+ var val = t[ i ]
40
+ if ( callback.call( thisp, val, i, t ) ) newArray.push( val )
41
+ }
42
+ }
43
+ return newArray
44
+ }
45
+ }
46
+
47
+
48
+ // Index of array support
49
+ if ( ![].indexOf ) {
50
+ Array.prototype.indexOf = function( searchElement ) {
51
+ if ( this == null ) throw new TypeError()
52
+ var t = Object( this ), len = t.length >>> 0
53
+ if ( len === 0 ) return -1
54
+ var n = 0
55
+ if ( arguments.length > 1 ) {
56
+ n = Number( arguments[ 1 ] )
57
+ if ( n != n ) {
58
+ n = 0
59
+ }
60
+ else if ( n !== 0 && n != Infinity && n != -Infinity ) {
61
+ n = ( n > 0 || -1 ) * Math.floor( Math.abs( n ) )
62
+ }
63
+ }
64
+ if ( n >= len ) return -1
65
+ var k = n >= 0 ? n : Math.max( len - Math.abs( n ), 0 )
66
+ for ( ; k < len; k++ ) {
67
+ if ( k in t && t[ k ] === searchElement ) return k
68
+ }
69
+ return -1
70
+ }
71
+ }
72
+
73
+
74
+ /*!
75
  * Cross-Browser Split 1.1.1
76
  * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
77
  * Available under the MIT License
78
  * http://blog.stevenlevithan.com/archives/cross-browser-split
79
  */
80
+ var nativeSplit = String.prototype.split, compliantExecNpcg = /()??/.exec('')[1] === undefined
81
+ String.prototype.split = function(separator, limit) {
82
+ var str = this
83
+ if (Object.prototype.toString.call(separator) !== '[object RegExp]') {
84
+ return nativeSplit.call(str, separator, limit)
85
+ }
86
+ var output = [],
87
+ flags = (separator.ignoreCase ? 'i' : '') +
88
+ (separator.multiline ? 'm' : '') +
89
+ (separator.extended ? 'x' : '') +
90
+ (separator.sticky ? 'y' : ''),
91
+ lastLastIndex = 0,
92
+ separator2, match, lastIndex, lastLength
93
+ separator = new RegExp(separator.source, flags + 'g')
94
+ str += ''
95
+ if (!compliantExecNpcg) {
96
+ separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags)
97
+ }
98
+ limit = limit === undefined ? -1 >>> 0 : limit >>> 0
99
+ while (match = separator.exec(str)) {
100
+ lastIndex = match.index + match[0].length
101
+ if (lastIndex > lastLastIndex) {
102
+ output.push(str.slice(lastLastIndex, match.index))
103
+ if (!compliantExecNpcg && match.length > 1) {
104
+ match[0].replace(separator2, function () {
105
+ for (var i = 1; i < arguments.length - 2; i++) {
106
+ if (arguments[i] === undefined) {
107
+ match[i] = undefined
108
+ }
109
+ }
110
+ })
111
+ }
112
+ if (match.length > 1 && match.index < str.length) {
113
+ Array.prototype.push.apply(output, match.slice(1))
114
+ }
115
+ lastLength = match[0].length
116
+ lastLastIndex = lastIndex
117
+ if (output.length >= limit) {
118
+ break
119
+ }
120
+ }
121
+ if (separator.lastIndex === match.index) {
122
+ separator.lastIndex++
123
+ }
124
+ }
125
+ if (lastLastIndex === str.length) {
126
+ if (lastLength || !separator.test('')) {
127
+ output.push('')
128
+ }
129
+ } else {
130
+ output.push(str.slice(lastLastIndex))
131
+ }
132
+ return output.length > limit ? output.slice(0, limit) : output
133
+ };
lib/simple-admin-pages/lib/pickadate/picker.date.js CHANGED
@@ -1,5 +1,1350 @@
1
  /*!
2
- * Date picker for pickadate.js v3.5.0
3
  * http://amsul.github.io/pickadate.js/date.htm
4
  */
5
- !function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0].value,e=a.$node.data("value"),f=e||d,g=e?b.formatSubmit:b.format,h=function(){return"rtl"===getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),f?c.set("select",f,{format:g}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return h()?-1:1},37:function(){return h()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",[d.getFullYear(),d.getMonth(),d.getDate()],{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})}).on("open",function(){a.$root.find("button, select").attr("disabled",!1)}).on("close",function(){a.$root.find("button, select").attr("disabled",!0)})}var d=7,e=6,f=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var e,g=this;return c=void 0===c?a:c,c==-1/0||1/0==c?e=c:b.isPlainObject(c)&&f.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=f.isDate(c)?c:g.create().obj):c=f.isInteger(c)||f.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:e||c.getFullYear(),month:e||c.getMonth(),date:e||c.getDate(),day:e||c.getDay(),obj:e||c,pick:e||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||f.isDate(a)?d.create(a):a};return f.isInteger(a)||(a=e(a)),f.isInteger(c)||(c=e(c)),f.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:f.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return b?f.isInteger(b)&&(b=c.now(a,b,{rel:b})):b="min"==a?-1/0:1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var e,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?e=!0:d>c.pick&&(g=!0)}return f.isInteger(a)}).length;if((!d||!d.nav)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||e||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!e&&0>l)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return f.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||f.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,e={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?f.trigger(c,d,[b,e]):a.replace(/^!/,"").length;c&&(e[a]=b.substr(0,g)),b=b.substr(g)}),[e.yyyy||e.yy,+(e.mm||e.m)-1,e.dd||e.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?f.digits(a):b.date},dd:function(a,b){return a?2:f.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?f.digits(a):b.month+1},mm:function(a,b){return a?2:f.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return f.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return f.isInteger(a)&&f.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(f.isDate(a)||b.isArray(a))&&(f.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to):!1},c.prototype.isDateOverlap=function(a,c){var d=this;return f.isInteger(a)&&(f.isDate(c)||b.isArray(c))?a===d.create(c).day+1:f.isInteger(c)&&(f.isDate(a)||b.isArray(a))?c===d.create(a).day+1:b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,g=0;g<e.length;g+=1)if(d.isDateExact(a,e[g])){c=!0;break}c||(f.isInteger(a)||f.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,g=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,h,i,j;for(i=0;g>i;i+=1){if(h=e[i],d.isDateExact(h,a)){c=e[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):f.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;g>i;i+=1)if(d.isDateExact(e[i],a)){e[i]=null;break}if(j)for(i=0;g>i;i+=1)if(d.isDateOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,g=b.item,h=g.now,i=g.select,j=g.highlight,k=g.view,l=g.disable,m=g.min,n=g.max,o=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),f.node("thead",f.node("tr",f.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysShort).slice(0),c.weekdaysFull.slice(0)),p=function(a){return f.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&k.year>=n.year&&k.month>=n.month||!a&&k.year<=m.year&&k.month<=m.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+f.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},q=function(){var d=c.showMonthsShort?c.monthsShort:c.monthsFull;return c.selectMonths?f.node("select",f.group({min:0,max:11,i:1,node:"option",item:function(a){return[d[a],0,"value="+a+(k.month==a?" selected":"")+(k.year==m.year&&a<m.month||k.year==n.year&&a>n.month?" disabled":"")]}}),c.klass.selectMonth,(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):f.node("div",d[k.month],c.klass.month)},r=function(){var d=k.year,e=c.selectYears===!0?5:~~(c.selectYears/2);if(e){var g=m.year,h=n.year,i=d-e,j=d+e;if(g>i&&(j+=g-i,i=g),j>h){var l=i-g,o=j-h;i-=l>o?o:l,j=h}return f.node("select",f.group({min:i,max:j,i:1,node:"option",item:function(a){return[a,0,"value="+a+(d==a?" selected":"")]}}),c.klass.selectYear,(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return f.node("div",d,c.klass.year)};return f.node("div",(c.selectYears?r()+q():q()+r())+p()+p(1),c.klass.header)+f.node("table",o+f.node("tbody",f.group({min:0,max:e-1,i:1,node:"tr",item:function(a){var e=c.firstDay&&0===b.create([k.year,k.month,1]).day?-7:0;return[f.group({min:d*a-k.day+e+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([k.year,k.month,a+(c.firstDay?1:0)]);var d=i&&i.pick==a.pick,e=j&&j.pick==a.pick,g=l&&b.disabled(a)||a.pick<m.pick||a.pick>n.pick;return[f.node("div",a.date,function(b){return b.push(k.month==a.month?c.klass.infocus:c.klass.outfocus),h.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),e&&b.push(c.klass.highlighted),g&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+f.ariaAttr({role:"gridcell",selected:d&&b.$node.val()===f.trigger(b.formats.toString,b,[c.format,a])?!0:null,activedescendant:e?!0:null,disabled:g?!0:null})),"",f.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+f.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0}))+f.node("div",f.node("button",c.today,c.klass.buttonToday,"type=button data-pick="+h.pick+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],today:"Today",clear:"Clear",format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /*!
2
+ * Date picker for pickadate.js v3.5.5
3
  * http://amsul.github.io/pickadate.js/date.htm
4
  */
5
+
6
+ (function ( factory ) {
7
+
8
+ // AMD.
9
+ if ( typeof define == 'function' && define.amd )
10
+ define( ['picker', 'jquery'], factory )
11
+
12
+ // Node.js/browserify.
13
+ else if ( typeof exports == 'object' )
14
+ module.exports = factory( require('./picker.js'), require('jquery') )
15
+
16
+ // Browser globals.
17
+ else factory( Picker, jQuery )
18
+
19
+ }(function( Picker, $ ) {
20
+
21
+
22
+ /**
23
+ * Globals and constants
24
+ */
25
+ var DAYS_IN_WEEK = 7,
26
+ WEEKS_IN_CALENDAR = 6,
27
+ _ = Picker._
28
+
29
+
30
+
31
+ /**
32
+ * The date picker constructor
33
+ */
34
+ function DatePicker( picker, settings ) {
35
+
36
+ var calendar = this,
37
+ element = picker.$node[ 0 ],
38
+ elementValue = element.value,
39
+ elementDataValue = picker.$node.data( 'value' ),
40
+ valueString = elementDataValue || elementValue,
41
+ formatString = elementDataValue ? settings.formatSubmit : settings.format,
42
+ isRTL = function() {
43
+
44
+ return element.currentStyle ?
45
+
46
+ // For IE.
47
+ element.currentStyle.direction == 'rtl' :
48
+
49
+ // For normal browsers.
50
+ getComputedStyle( picker.$root[0] ).direction == 'rtl'
51
+ }
52
+
53
+ calendar.settings = settings
54
+ calendar.$node = picker.$node
55
+
56
+ // The queue of methods that will be used to build item objects.
57
+ calendar.queue = {
58
+ min: 'measure create',
59
+ max: 'measure create',
60
+ now: 'now create',
61
+ select: 'parse create validate',
62
+ highlight: 'parse navigate create validate',
63
+ view: 'parse create validate viewset',
64
+ disable: 'deactivate',
65
+ enable: 'activate'
66
+ }
67
+
68
+ // The component's item object.
69
+ calendar.item = {}
70
+
71
+ calendar.item.clear = null
72
+ calendar.item.disable = ( settings.disable || [] ).slice( 0 )
73
+ calendar.item.enable = -(function( collectionDisabled ) {
74
+ return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1
75
+ })( calendar.item.disable )
76
+
77
+ calendar.
78
+ set( 'min', settings.min ).
79
+ set( 'max', settings.max ).
80
+ set( 'now' )
81
+
82
+ // When there’s a value, set the `select`, which in turn
83
+ // also sets the `highlight` and `view`.
84
+ if ( valueString ) {
85
+ calendar.set( 'select', valueString, {
86
+ format: formatString,
87
+ defaultValue: true
88
+ })
89
+ }
90
+
91
+ // If there’s no value, default to highlighting “today”.
92
+ else {
93
+ calendar.
94
+ set( 'select', null ).
95
+ set( 'highlight', calendar.item.now )
96
+ }
97
+
98
+
99
+ // The keycode to movement mapping.
100
+ calendar.key = {
101
+ 40: 7, // Down
102
+ 38: -7, // Up
103
+ 39: function() { return isRTL() ? -1 : 1 }, // Right
104
+ 37: function() { return isRTL() ? 1 : -1 }, // Left
105
+ go: function( timeChange ) {
106
+ var highlightedObject = calendar.item.highlight,
107
+ targetDate = new Date( highlightedObject.year, highlightedObject.month, highlightedObject.date + timeChange )
108
+ calendar.set(
109
+ 'highlight',
110
+ targetDate,
111
+ { interval: timeChange }
112
+ )
113
+ this.render()
114
+ }
115
+ }
116
+
117
+
118
+ // Bind some picker events.
119
+ picker.
120
+ on( 'render', function() {
121
+ picker.$root.find( '.' + settings.klass.selectMonth ).on( 'change', function() {
122
+ var value = this.value
123
+ if ( value ) {
124
+ picker.set( 'highlight', [ picker.get( 'view' ).year, value, picker.get( 'highlight' ).date ] )
125
+ picker.$root.find( '.' + settings.klass.selectMonth ).trigger( 'focus' )
126
+ }
127
+ })
128
+ picker.$root.find( '.' + settings.klass.selectYear ).on( 'change', function() {
129
+ var value = this.value
130
+ if ( value ) {
131
+ picker.set( 'highlight', [ value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] )
132
+ picker.$root.find( '.' + settings.klass.selectYear ).trigger( 'focus' )
133
+ }
134
+ })
135
+ }, 1 ).
136
+ on( 'open', function() {
137
+ var includeToday = ''
138
+ if ( calendar.disabled( calendar.get('now') ) ) {
139
+ includeToday = ':not(.' + settings.klass.buttonToday + ')'
140
+ }
141
+ picker.$root.find( 'button' + includeToday + ', select' ).attr( 'disabled', false )
142
+ }, 1 ).
143
+ on( 'close', function() {
144
+ picker.$root.find( 'button, select' ).attr( 'disabled', true )
145
+ }, 1 )
146
+
147
+ } //DatePicker
148
+
149
+
150
+ /**
151
+ * Set a datepicker item object.
152
+ */
153
+ DatePicker.prototype.set = function( type, value, options ) {
154
+
155
+ var calendar = this,
156
+ calendarItem = calendar.item
157
+
158
+ // If the value is `null` just set it immediately.
159
+ if ( value === null ) {
160
+ if ( type == 'clear' ) type = 'select'
161
+ calendarItem[ type ] = value
162
+ return calendar
163
+ }
164
+
165
+ // Otherwise go through the queue of methods, and invoke the functions.
166
+ // Update this as the time unit, and set the final value as this item.
167
+ // * In the case of `enable`, keep the queue but set `disable` instead.
168
+ // And in the case of `flip`, keep the queue but set `enable` instead.
169
+ calendarItem[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) {
170
+ value = calendar[ method ]( type, value, options )
171
+ return value
172
+ }).pop()
173
+
174
+ // Check if we need to cascade through more updates.
175
+ if ( type == 'select' ) {
176
+ calendar.set( 'highlight', calendarItem.select, options )
177
+ }
178
+ else if ( type == 'highlight' ) {
179
+ calendar.set( 'view', calendarItem.highlight, options )
180
+ }
181
+ else if ( type.match( /^(flip|min|max|disable|enable)$/ ) ) {
182
+ if ( calendarItem.select && calendar.disabled( calendarItem.select ) ) {
183
+ calendar.set( 'select', calendarItem.select, options )
184
+ }
185
+ if ( calendarItem.highlight && calendar.disabled( calendarItem.highlight ) ) {
186
+ calendar.set( 'highlight', calendarItem.highlight, options )
187
+ }
188
+ }
189
+
190
+ return calendar
191
+ } //DatePicker.prototype.set
192
+
193
+
194
+ /**
195
+ * Get a datepicker item object.
196
+ */
197
+ DatePicker.prototype.get = function( type ) {
198
+ return this.item[ type ]
199
+ } //DatePicker.prototype.get
200
+
201
+
202
+ /**
203
+ * Create a picker date object.
204
+ */
205
+ DatePicker.prototype.create = function( type, value, options ) {
206
+
207
+ var isInfiniteValue,
208
+ calendar = this
209
+
210
+ // If there’s no value, use the type as the value.
211
+ value = value === undefined ? type : value
212
+
213
+
214
+ // If it’s infinity, update the value.
215
+ if ( value == -Infinity || value == Infinity ) {
216
+ isInfiniteValue = value
217
+ }
218
+
219
+ // If it’s an object, use the native date object.
220
+ else if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
221
+ value = value.obj
222
+ }
223
+
224
+ // If it’s an array, convert it into a date and make sure
225
+ // that it’s a valid date – otherwise default to today.
226
+ else if ( $.isArray( value ) ) {
227
+ value = new Date( value[ 0 ], value[ 1 ], value[ 2 ] )
228
+ value = _.isDate( value ) ? value : calendar.create().obj
229
+ }
230
+
231
+ // If it’s a number or date object, make a normalized date.
232
+ else if ( _.isInteger( value ) || _.isDate( value ) ) {
233
+ value = calendar.normalize( new Date( value ), options )
234
+ }
235
+
236
+ // If it’s a literal true or any other case, set it to now.
237
+ else /*if ( value === true )*/ {
238
+ value = calendar.now( type, value, options )
239
+ }
240
+
241
+ // Return the compiled object.
242
+ return {
243
+ year: isInfiniteValue || value.getFullYear(),
244
+ month: isInfiniteValue || value.getMonth(),
245
+ date: isInfiniteValue || value.getDate(),
246
+ day: isInfiniteValue || value.getDay(),
247
+ obj: isInfiniteValue || value,
248
+ pick: isInfiniteValue || value.getTime()
249
+ }
250
+ } //DatePicker.prototype.create
251
+
252
+
253
+ /**
254
+ * Create a range limit object using an array, date object,
255
+ * literal “true”, or integer relative to another time.
256
+ */
257
+ DatePicker.prototype.createRange = function( from, to ) {
258
+
259
+ var calendar = this,
260
+ createDate = function( date ) {
261
+ if ( date === true || $.isArray( date ) || _.isDate( date ) ) {
262
+ return calendar.create( date )
263
+ }
264
+ return date
265
+ }
266
+
267
+ // Create objects if possible.
268
+ if ( !_.isInteger( from ) ) {
269
+ from = createDate( from )
270
+ }
271
+ if ( !_.isInteger( to ) ) {
272
+ to = createDate( to )
273
+ }
274
+
275
+ // Create relative dates.
276
+ if ( _.isInteger( from ) && $.isPlainObject( to ) ) {
277
+ from = [ to.year, to.month, to.date + from ];
278
+ }
279
+ else if ( _.isInteger( to ) && $.isPlainObject( from ) ) {
280
+ to = [ from.year, from.month, from.date + to ];
281
+ }
282
+
283
+ return {
284
+ from: createDate( from ),
285
+ to: createDate( to )
286
+ }
287
+ } //DatePicker.prototype.createRange
288
+
289
+
290
+ /**
291
+ * Check if a date unit falls within a date range object.
292
+ */
293
+ DatePicker.prototype.withinRange = function( range, dateUnit ) {
294
+ range = this.createRange(range.from, range.to)
295
+ return dateUnit.pick >= range.from.pick && dateUnit.pick <= range.to.pick
296
+ }
297
+
298
+
299
+ /**
300
+ * Check if two date range objects overlap.
301
+ */
302
+ DatePicker.prototype.overlapRanges = function( one, two ) {
303
+
304
+ var calendar = this
305
+
306
+ // Convert the ranges into comparable dates.
307
+ one = calendar.createRange( one.from, one.to )
308
+ two = calendar.createRange( two.from, two.to )
309
+
310
+ return calendar.withinRange( one, two.from ) || calendar.withinRange( one, two.to ) ||
311
+ calendar.withinRange( two, one.from ) || calendar.withinRange( two, one.to )
312
+ }
313
+
314
+
315
+ /**
316
+ * Get the date today.
317
+ */
318
+ DatePicker.prototype.now = function( type, value, options ) {
319
+ value = new Date()
320
+ if ( options && options.rel ) {
321
+ value.setDate( value.getDate() + options.rel )
322
+ }
323
+ return this.normalize( value, options )
324
+ }
325
+
326
+
327
+ /**
328
+ * Navigate to next/prev month.
329
+ */
330
+ DatePicker.prototype.navigate = function( type, value, options ) {
331
+
332
+ var targetDateObject,
333
+ targetYear,
334
+ targetMonth,
335
+ targetDate,
336
+ isTargetArray = $.isArray( value ),
337
+ isTargetObject = $.isPlainObject( value ),
338
+ viewsetObject = this.item.view/*,
339
+ safety = 100*/
340
+
341
+
342
+ if ( isTargetArray || isTargetObject ) {
343
+
344
+ if ( isTargetObject ) {
345
+ targetYear = value.year
346
+ targetMonth = value.month
347
+ targetDate = value.date
348
+ }
349
+ else {
350
+ targetYear = +value[0]
351
+ targetMonth = +value[1]
352
+ targetDate = +value[2]
353
+ }
354
+
355
+ // If we’re navigating months but the view is in a different
356
+ // month, navigate to the view’s year and month.
357
+ if ( options && options.nav && viewsetObject && viewsetObject.month !== targetMonth ) {
358
+ targetYear = viewsetObject.year
359
+ targetMonth = viewsetObject.month
360
+ }
361
+
362
+ // Figure out the expected target year and month.
363
+ targetDateObject = new Date( targetYear, targetMonth + ( options && options.nav ? options.nav : 0 ), 1 )
364
+ targetYear = targetDateObject.getFullYear()
365
+ targetMonth = targetDateObject.getMonth()
366
+
367
+ // If the month we’re going to doesn’t have enough days,
368
+ // keep decreasing the date until we reach the month’s last date.
369
+ while ( /*safety &&*/ new Date( targetYear, targetMonth, targetDate ).getMonth() !== targetMonth ) {
370
+ targetDate -= 1
371
+ /*safety -= 1
372
+ if ( !safety ) {
373
+ throw 'Fell into an infinite loop while navigating to ' + new Date( targetYear, targetMonth, targetDate ) + '.'
374
+ }*/
375
+ }
376
+
377
+ value = [ targetYear, targetMonth, targetDate ]
378
+ }
379
+
380
+ return value
381
+ } //DatePicker.prototype.navigate
382
+
383
+
384
+ /**
385
+ * Normalize a date by setting the hours to midnight.
386
+ */
387
+ DatePicker.prototype.normalize = function( value/*, options*/ ) {
388
+ value.setHours( 0, 0, 0, 0 )
389
+ return value
390
+ }
391
+
392
+
393
+ /**
394
+ * Measure the range of dates.
395
+ */
396
+ DatePicker.prototype.measure = function( type, value/*, options*/ ) {
397
+
398
+ var calendar = this
399
+
400
+ // If it’s anything false-y, remove the limits.
401
+ if ( !value ) {
402
+ value = type == 'min' ? -Infinity : Infinity
403
+ }
404
+
405
+ // If it’s a string, parse it.
406
+ else if ( typeof value == 'string' ) {
407
+ value = calendar.parse( type, value )
408
+ }
409
+
410
+ // If it's an integer, get a date relative to today.
411
+ else if ( _.isInteger( value ) ) {
412
+ value = calendar.now( type, value, { rel: value } )
413
+ }
414
+
415
+ return value
416
+ } ///DatePicker.prototype.measure
417
+
418
+
419
+ /**
420
+ * Create a viewset object based on navigation.
421
+ */
422
+ DatePicker.prototype.viewset = function( type, dateObject/*, options*/ ) {
423
+ return this.create([ dateObject.year, dateObject.month, 1 ])
424
+ }
425
+
426
+
427
+ /**
428
+ * Validate a date as enabled and shift if needed.
429
+ */
430
+ DatePicker.prototype.validate = function( type, dateObject, options ) {
431
+
432
+ var calendar = this,
433
+
434
+ // Keep a reference to the original date.
435
+ originalDateObject = dateObject,
436
+
437
+ // Make sure we have an interval.
438
+ interval = options && options.interval ? options.interval : 1,
439
+
440
+ // Check if the calendar enabled dates are inverted.
441
+ isFlippedBase = calendar.item.enable === -1,
442
+
443
+ // Check if we have any enabled dates after/before now.
444
+ hasEnabledBeforeTarget, hasEnabledAfterTarget,
445
+
446
+ // The min & max limits.
447
+ minLimitObject = calendar.item.min,
448
+ maxLimitObject = calendar.item.max,
449
+
450
+ // Check if we’ve reached the limit during shifting.
451
+ reachedMin, reachedMax,
452
+
453
+ // Check if the calendar is inverted and at least one weekday is enabled.
454
+ hasEnabledWeekdays = isFlippedBase && calendar.item.disable.filter( function( value ) {
455
+
456
+ // If there’s a date, check where it is relative to the target.
457
+ if ( $.isArray( value ) ) {
458
+ var dateTime = calendar.create( value ).pick
459
+ if ( dateTime < dateObject.pick ) hasEnabledBeforeTarget = true
460
+ else if ( dateTime > dateObject.pick ) hasEnabledAfterTarget = true
461
+ }
462
+
463
+ // Return only integers for enabled weekdays.
464
+ return _.isInteger( value )
465
+ }).length/*,
466
+
467
+ safety = 100*/
468
+
469
+
470
+
471
+ // Cases to validate for:
472
+ // [1] Not inverted and date disabled.
473
+ // [2] Inverted and some dates enabled.
474
+ // [3] Not inverted and out of range.
475
+ //
476
+ // Cases to **not** validate for:
477
+ // • Navigating months.
478
+ // • Not inverted and date enabled.
479
+ // • Inverted and all dates disabled.
480
+ // • ..and anything else.
481
+ if ( !options || (!options.nav && !options.defaultValue) ) if (
482
+ /* 1 */ ( !isFlippedBase && calendar.disabled( dateObject ) ) ||
483
+ /* 2 */ ( isFlippedBase && calendar.disabled( dateObject ) && ( hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget ) ) ||
484
+ /* 3 */ ( !isFlippedBase && (dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick) )
485
+ ) {
486
+
487
+
488
+ // When inverted, flip the direction if there aren’t any enabled weekdays
489
+ // and there are no enabled dates in the direction of the interval.
490
+ if ( isFlippedBase && !hasEnabledWeekdays && ( ( !hasEnabledAfterTarget && interval > 0 ) || ( !hasEnabledBeforeTarget && interval < 0 ) ) ) {
491
+ interval *= -1
492
+ }
493
+
494
+
495
+ // Keep looping until we reach an enabled date.
496
+ while ( /*safety &&*/ calendar.disabled( dateObject ) ) {
497
+
498
+ /*safety -= 1
499
+ if ( !safety ) {
500
+ throw 'Fell into an infinite loop while validating ' + dateObject.obj + '.'
501
+ }*/
502
+
503
+
504
+ // If we’ve looped into the next/prev month with a large interval, return to the original date and flatten the interval.
505
+ if ( Math.abs( interval ) > 1 && ( dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month ) ) {
506
+ dateObject = originalDateObject
507
+ interval = interval > 0 ? 1 : -1
508
+ }
509
+
510
+
511
+ // If we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
512
+ if ( dateObject.pick <= minLimitObject.pick ) {
513
+ reachedMin = true
514
+ interval = 1
515
+ dateObject = calendar.create([
516
+ minLimitObject.year,
517
+ minLimitObject.month,
518
+ minLimitObject.date + (dateObject.pick === minLimitObject.pick ? 0 : -1)
519
+ ])
520
+ }
521
+ else if ( dateObject.pick >= maxLimitObject.pick ) {
522
+ reachedMax = true
523
+ interval = -1
524
+ dateObject = calendar.create([
525
+ maxLimitObject.year,
526
+ maxLimitObject.month,
527
+ maxLimitObject.date + (dateObject.pick === maxLimitObject.pick ? 0 : 1)
528
+ ])
529
+ }
530
+
531
+
532
+ // If we’ve reached both limits, just break out of the loop.
533
+ if ( reachedMin && reachedMax ) {
534
+ break
535
+ }
536
+
537
+
538
+ // Finally, create the shifted date using the interval and keep looping.
539
+ dateObject = calendar.create([ dateObject.year, dateObject.month, dateObject.date + interval ])
540
+ }
541
+
542
+ } //endif
543
+
544
+
545
+ // Return the date object settled on.
546
+ return dateObject
547
+ } //DatePicker.prototype.validate
548
+
549
+
550
+ /**
551
+ * Check if a date is disabled.
552
+ */
553
+ DatePicker.prototype.disabled = function( dateToVerify ) {
554
+
555
+ var
556
+ calendar = this,
557
+
558
+ // Filter through the disabled dates to check if this is one.
559
+ isDisabledMatch = calendar.item.disable.filter( function( dateToDisable ) {
560
+
561
+ // If the date is a number, match the weekday with 0index and `firstDay` check.
562
+ if ( _.isInteger( dateToDisable ) ) {
563
+ return dateToVerify.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7
564
+ }
565
+
566
+ // If it’s an array or a native JS date, create and match the exact date.
567
+ if ( $.isArray( dateToDisable ) || _.isDate( dateToDisable ) ) {
568
+ return dateToVerify.pick === calendar.create( dateToDisable ).pick
569
+ }
570
+
571
+ // If it’s an object, match a date within the “from” and “to” range.
572
+ if ( $.isPlainObject( dateToDisable ) ) {
573
+ return calendar.withinRange( dateToDisable, dateToVerify )
574
+ }
575
+ })
576
+
577
+ // If this date matches a disabled date, confirm it’s not inverted.
578
+ isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function( dateToDisable ) {
579
+ return $.isArray( dateToDisable ) && dateToDisable[3] == 'inverted' ||
580
+ $.isPlainObject( dateToDisable ) && dateToDisable.inverted
581
+ }).length
582
+
583
+ // Check the calendar “enabled” flag and respectively flip the
584
+ // disabled state. Then also check if it’s beyond the min/max limits.
585
+ return calendar.item.enable === -1 ? !isDisabledMatch : isDisabledMatch ||
586
+ dateToVerify.pick < calendar.item.min.pick ||
587
+ dateToVerify.pick > calendar.item.max.pick
588
+
589
+ } //DatePicker.prototype.disabled
590
+
591
+
592
+ /**
593
+ * Parse a string into a usable type.
594
+ */
595
+ DatePicker.prototype.parse = function( type, value, options ) {
596
+
597
+ var calendar = this,
598
+ parsingObject = {}
599
+
600
+ // If it’s already parsed, we’re good.
601
+ if ( !value || typeof value != 'string' ) {
602
+ return value
603
+ }
604
+
605
+ // We need a `.format` to parse the value with.
606
+ if ( !( options && options.format ) ) {
607
+ options = options || {}
608
+ options.format = calendar.settings.format
609
+ }
610
+
611
+ // Convert the format into an array and then map through it.
612
+ calendar.formats.toArray( options.format ).map( function( label ) {
613
+
614
+ var
615
+ // Grab the formatting label.
616
+ formattingLabel = calendar.formats[ label ],
617
+
618
+ // The format length is from the formatting label function or the
619
+ // label length without the escaping exclamation (!) mark.
620
+ formatLength = formattingLabel ? _.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length
621
+
622
+ // If there's a format label, split the value up to the format length.
623
+ // Then add it to the parsing object with appropriate label.
624
+ if ( formattingLabel ) {
625
+ parsingObject[ label ] = value.substr( 0, formatLength )
626
+ }
627
+
628
+ // Update the value as the substring from format length to end.
629
+ value = value.substr( formatLength )
630
+ })
631
+
632
+ // Compensate for month 0index.
633
+ return [
634
+ parsingObject.yyyy || parsingObject.yy,
635
+ +( parsingObject.mm || parsingObject.m ) - 1,
636
+ parsingObject.dd || parsingObject.d
637
+ ]
638
+ } //DatePicker.prototype.parse
639
+
640
+
641
+ /**
642
+ * Various formats to display the object in.
643
+ */
644
+ DatePicker.prototype.formats = (function() {
645
+
646
+ // Return the length of the first word in a collection.
647
+ function getWordLengthFromCollection( string, collection, dateObject ) {
648
+
649
+ // Grab the first word from the string.
650
+ // Regex pattern from http://stackoverflow.com/q/150033
651
+ var word = string.match( /[^\x00-\x7F]+|\w+/ )[ 0 ]
652
+
653
+ // If there's no month index, add it to the date object
654
+ if ( !dateObject.mm && !dateObject.m ) {
655
+ dateObject.m = collection.indexOf( word ) + 1
656
+ }
657
+
658
+ // Return the length of the word.
659
+ return word.length
660
+ }
661
+
662
+ // Get the length of the first word in a string.
663
+ function getFirstWordLength( string ) {
664
+ return string.match( /\w+/ )[ 0 ].length
665
+ }
666
+
667
+ return {
668
+
669
+ d: function( string, dateObject ) {
670
+
671
+ // If there's string, then get the digits length.
672
+ // Otherwise return the selected date.
673
+ return string ? _.digits( string ) : dateObject.date
674
+ },
675
+ dd: function( string, dateObject ) {
676
+
677
+ // If there's a string, then the length is always 2.
678
+ // Otherwise return the selected date with a leading zero.
679
+ return string ? 2 : _.lead( dateObject.date )
680
+ },
681
+ ddd: function( string, dateObject ) {
682
+
683
+ // If there's a string, then get the length of the first word.
684
+ // Otherwise return the short selected weekday.
685
+ return string ? getFirstWordLength( string ) : this.settings.weekdaysShort[ dateObject.day ]
686
+ },
687
+ dddd: function( string, dateObject ) {
688
+
689
+ // If there's a string, then get the length of the first word.
690
+ // Otherwise return the full selected weekday.
691
+ return string ? getFirstWordLength( string ) : this.settings.weekdaysFull[ dateObject.day ]
692
+ },
693
+ m: function( string, dateObject ) {
694
+
695
+ // If there's a string, then get the length of the digits
696
+ // Otherwise return the selected month with 0index compensation.
697
+ return string ? _.digits( string ) : dateObject.month + 1
698
+ },
699
+ mm: function( string, dateObject ) {
700
+
701
+ // If there's a string, then the length is always 2.
702
+ // Otherwise return the selected month with 0index and leading zero.
703
+ return string ? 2 : _.lead( dateObject.month + 1 )
704
+ },
705
+ mmm: function( string, dateObject ) {
706
+
707
+ var collection = this.settings.monthsShort
708
+
709
+ // If there's a string, get length of the relevant month from the short
710
+ // months collection. Otherwise return the selected month from that collection.
711
+ return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ]
712
+ },
713
+ mmmm: function( string, dateObject ) {
714
+
715
+ var collection = this.settings.monthsFull
716
+
717
+ // If there's a string, get length of the relevant month from the full
718
+ // months collection. Otherwise return the selected month from that collection.
719
+ return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ]
720
+ },
721
+ yy: function( string, dateObject ) {
722
+
723
+ // If there's a string, then the length is always 2.
724
+ // Otherwise return the selected year by slicing out the first 2 digits.
725
+ return string ? 2 : ( '' + dateObject.year ).slice( 2 )
726
+ },
727
+ yyyy: function( string, dateObject ) {
728
+
729
+ // If there's a string, then the length is always 4.
730
+ // Otherwise return the selected year.
731
+ return string ? 4 : dateObject.year
732
+ },
733
+
734
+ // Create an array by splitting the formatting string passed.
735
+ toArray: function( formatString ) { return formatString.split( /(d{1,4}|m{1,4}|y{4}|yy|!.)/g ) },
736
+
737
+ // Format an object into a string using the formatting options.
738
+ toString: function ( formatString, itemObject ) {
739
+ var calendar = this
740
+ return calendar.formats.toArray( formatString ).map( function( label ) {
741
+ return _.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' )
742
+ }).join( '' )
743
+ }
744
+ }
745
+ })() //DatePicker.prototype.formats
746
+
747
+
748
+
749
+
750
+ /**
751
+ * Check if two date units are the exact.
752
+ */
753
+ DatePicker.prototype.isDateExact = function( one, two ) {
754
+
755
+ var calendar = this
756
+
757
+ // When we’re working with weekdays, do a direct comparison.
758
+ if (
759
+ ( _.isInteger( one ) && _.isInteger( two ) ) ||
760
+ ( typeof one == 'boolean' && typeof two == 'boolean' )
761
+ ) {
762
+ return one === two
763
+ }
764
+
765
+ // When we’re working with date representations, compare the “pick” value.
766
+ if (
767
+ ( _.isDate( one ) || $.isArray( one ) ) &&
768
+ ( _.isDate( two ) || $.isArray( two ) )
769
+ ) {
770
+ return calendar.create( one ).pick === calendar.create( two ).pick
771
+ }
772
+
773
+ // When we’re working with range objects, compare the “from” and “to”.
774
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
775
+ return calendar.isDateExact( one.from, two.from ) && calendar.isDateExact( one.to, two.to )
776
+ }
777
+
778
+ return false
779
+ }
780
+
781
+
782
+ /**
783
+ * Check if two date units overlap.
784
+ */
785
+ DatePicker.prototype.isDateOverlap = function( one, two ) {
786
+
787
+ var calendar = this,
788
+ firstDay = calendar.settings.firstDay ? 1 : 0
789
+
790
+ // When we’re working with a weekday index, compare the days.
791
+ if ( _.isInteger( one ) && ( _.isDate( two ) || $.isArray( two ) ) ) {
792
+ one = one % 7 + firstDay
793
+ return one === calendar.create( two ).day + 1
794
+ }
795
+ if ( _.isInteger( two ) && ( _.isDate( one ) || $.isArray( one ) ) ) {
796
+ two = two % 7 + firstDay
797
+ return two === calendar.create( one ).day + 1
798
+ }
799
+
800
+ // When we’re working with range objects, check if the ranges overlap.
801
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
802
+ return calendar.overlapRanges( one, two )
803
+ }
804
+
805
+ return false
806
+ }
807
+
808
+
809
+ /**
810
+ * Flip the “enabled” state.
811
+ */
812
+ DatePicker.prototype.flipEnable = function(val) {
813
+ var itemObject = this.item
814
+ itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1)
815
+ }
816
+
817
+
818
+ /**
819
+ * Mark a collection of dates as “disabled”.
820
+ */
821
+ DatePicker.prototype.deactivate = function( type, datesToDisable ) {
822
+
823
+ var calendar = this,
824
+ disabledItems = calendar.item.disable.slice(0)
825
+
826
+
827
+ // If we’re flipping, that’s all we need to do.
828
+ if ( datesToDisable == 'flip' ) {
829
+ calendar.flipEnable()
830
+ }
831
+
832
+ else if ( datesToDisable === false ) {
833
+ calendar.flipEnable(1)
834
+ disabledItems = []
835
+ }
836
+
837
+ else if ( datesToDisable === true ) {
838
+ calendar.flipEnable(-1)
839
+ disabledItems = []
840
+ }
841
+
842
+ // Otherwise go through the dates to disable.
843
+ else {
844
+
845
+ datesToDisable.map(function( unitToDisable ) {
846
+
847
+ var matchFound
848
+
849
+ // When we have disabled items, check for matches.
850
+ // If something is matched, immediately break out.
851
+ for ( var index = 0; index < disabledItems.length; index += 1 ) {
852
+ if ( calendar.isDateExact( unitToDisable, disabledItems[index] ) ) {
853
+ matchFound = true
854
+ break
855
+ }
856
+ }
857
+
858
+ // If nothing was found, add the validated unit to the collection.
859
+ if ( !matchFound ) {
860
+ if (
861
+ _.isInteger( unitToDisable ) ||
862
+ _.isDate( unitToDisable ) ||
863
+ $.isArray( unitToDisable ) ||
864
+ ( $.isPlainObject( unitToDisable ) && unitToDisable.from && unitToDisable.to )
865
+ ) {
866
+ disabledItems.push( unitToDisable )
867
+ }
868
+ }
869
+ })
870
+ }
871
+
872
+ // Return the updated collection.
873
+ return disabledItems
874
+ } //DatePicker.prototype.deactivate
875
+
876
+
877
+ /**
878
+ * Mark a collection of dates as “enabled”.
879
+ */
880
+ DatePicker.prototype.activate = function( type, datesToEnable ) {
881
+
882
+ var calendar = this,
883
+ disabledItems = calendar.item.disable,
884
+ disabledItemsCount = disabledItems.length
885
+
886
+ // If we’re flipping, that’s all we need to do.
887
+ if ( datesToEnable == 'flip' ) {
888
+ calendar.flipEnable()
889
+ }
890
+
891
+ else if ( datesToEnable === true ) {
892
+ calendar.flipEnable(1)
893
+ disabledItems = []
894
+ }
895
+
896
+ else if ( datesToEnable === false ) {
897
+ calendar.flipEnable(-1)
898
+ disabledItems = []
899
+ }
900
+
901
+ // Otherwise go through the disabled dates.
902
+ else {
903
+
904
+ datesToEnable.map(function( unitToEnable ) {
905
+
906
+ var matchFound,
907
+ disabledUnit,
908
+ index,
909
+ isExactRange
910
+
911
+ // Go through the disabled items and try to find a match.
912
+ for ( index = 0; index < disabledItemsCount; index += 1 ) {
913
+
914
+ disabledUnit = disabledItems[index]
915
+
916
+ // When an exact match is found, remove it from the collection.
917
+ if ( calendar.isDateExact( disabledUnit, unitToEnable ) ) {
918
+ matchFound = disabledItems[index] = null
919
+ isExactRange = true
920
+ break
921
+ }
922
+
923
+ // When an overlapped match is found, add the “inverted” state to it.
924
+ else if ( calendar.isDateOverlap( disabledUnit, unitToEnable ) ) {
925
+ if ( $.isPlainObject( unitToEnable ) ) {
926
+ unitToEnable.inverted = true
927
+ matchFound = unitToEnable
928
+ }
929
+ else if ( $.isArray( unitToEnable ) ) {
930
+ matchFound = unitToEnable
931
+ if ( !matchFound[3] ) matchFound.push( 'inverted' )
932
+ }
933
+ else if ( _.isDate( unitToEnable ) ) {
934
+ matchFound = [ unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted' ]
935
+ }
936
+ break
937
+ }
938
+ }
939
+
940
+ // If a match was found, remove a previous duplicate entry.
941
+ if ( matchFound ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
942
+ if ( calendar.isDateExact( disabledItems[index], unitToEnable ) ) {
943
+ disabledItems[index] = null
944
+ break
945
+ }
946
+ }
947
+
948
+ // In the event that we’re dealing with an exact range of dates,
949
+ // make sure there are no “inverted” dates because of it.
950
+ if ( isExactRange ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
951
+ if ( calendar.isDateOverlap( disabledItems[index], unitToEnable ) ) {
952
+ disabledItems[index] = null
953
+ break
954
+ }
955
+ }
956
+
957
+ // If something is still matched, add it into the collection.
958
+ if ( matchFound ) {
959
+ disabledItems.push( matchFound )
960
+ }
961
+ })
962
+ }
963
+
964
+ // Return the updated collection.
965
+ return disabledItems.filter(function( val ) { return val != null })
966
+ } //DatePicker.prototype.activate
967
+
968
+
969
+ /**
970
+ * Create a string for the nodes in the picker.
971
+ */
972
+ DatePicker.prototype.nodes = function( isOpen ) {
973
+
974
+ var
975
+ calendar = this,
976
+ settings = calendar.settings,
977
+ calendarItem = calendar.item,
978
+ nowObject = calendarItem.now,
979
+ selectedObject = calendarItem.select,
980
+ highlightedObject = calendarItem.highlight,
981
+ viewsetObject = calendarItem.view,
982
+ disabledCollection = calendarItem.disable,
983
+ minLimitObject = calendarItem.min,
984
+ maxLimitObject = calendarItem.max,
985
+
986
+
987
+ // Create the calendar table head using a copy of weekday labels collection.
988
+ // * We do a copy so we don't mutate the original array.
989
+ tableHead = (function( collection, fullCollection ) {
990
+
991
+ // If the first day should be Monday, move Sunday to the end.
992
+ if ( settings.firstDay ) {
993
+ collection.push( collection.shift() )
994
+ fullCollection.push( fullCollection.shift() )
995
+ }
996
+
997
+ // Create and return the table head group.
998
+ return _.node(
999
+ 'thead',
1000
+ _.node(
1001
+ 'tr',
1002
+ _.group({
1003
+ min: 0,
1004
+ max: DAYS_IN_WEEK - 1,
1005
+ i: 1,
1006
+ node: 'th',
1007
+ item: function( counter ) {
1008
+ return [
1009
+ collection[ counter ],
1010
+ settings.klass.weekdays,
1011
+ 'scope=col title="' + fullCollection[ counter ] + '"'
1012
+ ]
1013
+ }
1014
+ })
1015
+ )
1016
+ ) //endreturn
1017
+ })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ), settings.weekdaysFull.slice( 0 ) ), //tableHead
1018
+
1019
+
1020
+ // Create the nav for next/prev month.
1021
+ createMonthNav = function( next ) {
1022
+
1023
+ // Otherwise, return the created month tag.
1024
+ return _.node(
1025
+ 'div',
1026
+ ' ',
1027
+ settings.klass[ 'nav' + ( next ? 'Next' : 'Prev' ) ] + (
1028
+
1029
+ // If the focused month is outside the range, disabled the button.
1030
+ ( next && viewsetObject.year >= maxLimitObject.year && viewsetObject.month >= maxLimitObject.month ) ||
1031
+ ( !next && viewsetObject.year <= minLimitObject.year && viewsetObject.month <= minLimitObject.month ) ?
1032
+ ' ' + settings.klass.navDisabled : ''
1033
+ ),
1034
+ 'data-nav=' + ( next || -1 ) + ' ' +
1035
+ _.ariaAttr({
1036
+ role: 'button',
1037
+ controls: calendar.$node[0].id + '_table'
1038
+ }) + ' ' +
1039
+ 'title="' + (next ? settings.labelMonthNext : settings.labelMonthPrev ) + '"'
1040
+ ) //endreturn
1041
+ }, //createMonthNav
1042
+
1043
+
1044
+ // Create the month label.
1045
+ createMonthLabel = function() {
1046
+
1047
+ var monthsCollection = settings.showMonthsShort ? settings.monthsShort : settings.monthsFull
1048
+
1049
+ // If there are months to select, add a dropdown menu.
1050
+ if ( settings.selectMonths ) {
1051
+
1052
+ return _.node( 'select',
1053
+ _.group({
1054
+ min: 0,
1055
+ max: 11,
1056
+ i: 1,
1057
+ node: 'option',
1058
+ item: function( loopedMonth ) {
1059
+
1060
+ return [
1061
+
1062
+ // The looped month and no classes.
1063
+ monthsCollection[ loopedMonth ], 0,
1064
+
1065
+ // Set the value and selected index.
1066
+ 'value=' + loopedMonth +
1067
+ ( viewsetObject.month == loopedMonth ? ' selected' : '' ) +
1068
+ (
1069
+ (
1070
+ ( viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month ) ||
1071
+ ( viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month )
1072
+ ) ?
1073
+ ' disabled' : ''
1074
+ )
1075
+ ]
1076
+ }
1077
+ }),
1078
+ settings.klass.selectMonth,
1079
+ ( isOpen ? '' : 'disabled' ) + ' ' +
1080
+ _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' +
1081
+ 'title="' + settings.labelMonthSelect + '"'
1082
+ )
1083
+ }
1084
+
1085
+ // If there's a need for a month selector
1086
+ return _.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month )
1087
+ }, //createMonthLabel
1088
+
1089
+
1090
+ // Create the year label.
1091
+ createYearLabel = function() {
1092
+
1093
+ var focusedYear = viewsetObject.year,
1094
+
1095
+ // If years selector is set to a literal "true", set it to 5. Otherwise
1096
+ // divide in half to get half before and half after focused year.
1097
+ numberYears = settings.selectYears === true ? 5 : ~~( settings.selectYears / 2 )
1098
+
1099
+ // If there are years to select, add a dropdown menu.
1100
+ if ( numberYears ) {
1101
+
1102
+ var
1103
+ minYear = minLimitObject.year,
1104
+ maxYear = maxLimitObject.year,
1105
+ lowestYear = focusedYear - numberYears,
1106
+ highestYear = focusedYear + numberYears
1107
+
1108
+ // If the min year is greater than the lowest year, increase the highest year
1109
+ // by the difference and set the lowest year to the min year.
1110
+ if ( minYear > lowestYear ) {
1111
+ highestYear += minYear - lowestYear
1112
+ lowestYear = minYear
1113
+ }
1114
+
1115
+ // If the max year is less than the highest year, decrease the lowest year
1116
+ // by the lower of the two: available and needed years. Then set the
1117
+ // highest year to the max year.
1118
+ if ( maxYear < highestYear ) {
1119
+
1120
+ var availableYears = lowestYear - minYear,
1121
+ neededYears = highestYear - maxYear
1122
+
1123
+ lowestYear -= availableYears > neededYears ? neededYears : availableYears
1124
+ highestYear = maxYear
1125
+ }
1126
+
1127
+ return _.node( 'select',
1128
+ _.group({
1129
+ min: lowestYear,
1130
+ max: highestYear,
1131
+ i: 1,
1132
+ node: 'option',
1133
+ item: function( loopedYear ) {
1134
+ return [
1135
+
1136
+ // The looped year and no classes.
1137
+ loopedYear, 0,
1138
+
1139
+ // Set the value and selected index.
1140
+ 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' )
1141
+ ]
1142
+ }
1143
+ }),
1144
+ settings.klass.selectYear,
1145
+ ( isOpen ? '' : 'disabled' ) + ' ' + _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' +
1146
+ 'title="' + settings.labelYearSelect + '"'
1147
+ )
1148
+ }
1149
+
1150
+ // Otherwise just return the year focused
1151
+ return _.node( 'div', focusedYear, settings.klass.year )
1152
+ } //createYearLabel
1153
+
1154
+
1155
+ // Create and return the entire calendar.
1156
+ return _.node(
1157
+ 'div',
1158
+ ( settings.selectYears ? createYearLabel() + createMonthLabel() : createMonthLabel() + createYearLabel() ) +
1159
+ createMonthNav() + createMonthNav( 1 ),
1160
+ settings.klass.header
1161
+ ) + _.node(
1162
+ 'table',
1163
+ tableHead +
1164
+ _.node(
1165
+ 'tbody',
1166
+ _.group({
1167
+ min: 0,
1168
+ max: WEEKS_IN_CALENDAR - 1,
1169
+ i: 1,
1170
+ node: 'tr',
1171
+ item: function( rowCounter ) {
1172
+
1173
+ // If Monday is the first day and the month starts on Sunday, shift the date back a week.
1174
+ var shiftDateBy = settings.firstDay && calendar.create([ viewsetObject.year, viewsetObject.month, 1 ]).day === 0 ? -7 : 0
1175
+
1176
+ return [
1177
+ _.group({
1178
+ min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index
1179
+ max: function() {
1180
+ return this.min + DAYS_IN_WEEK - 1
1181
+ },
1182
+ i: 1,
1183
+ node: 'td',
1184
+ item: function( targetDate ) {
1185
+
1186
+ // Convert the time date from a relative date to a target date.
1187
+ targetDate = calendar.create([ viewsetObject.year, viewsetObject.month, targetDate + ( settings.firstDay ? 1 : 0 ) ])
1188
+
1189
+ var isSelected = selectedObject && selectedObject.pick == targetDate.pick,
1190
+ isHighlighted = highlightedObject && highlightedObject.pick == targetDate.pick,
1191
+ isDisabled = disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick,
1192
+ formattedDate = _.trigger( calendar.formats.toString, calendar, [ settings.format, targetDate ] )
1193
+
1194
+ return [
1195
+ _.node(
1196
+ 'div',
1197
+ targetDate.date,
1198
+ (function( klasses ) {
1199
+
1200
+ // Add the `infocus` or `outfocus` classes based on month in view.
1201
+ klasses.push( viewsetObject.month == targetDate.month ? settings.klass.infocus : settings.klass.outfocus )
1202
+
1203
+ // Add the `today` class if needed.
1204
+ if ( nowObject.pick == targetDate.pick ) {
1205
+ klasses.push( settings.klass.now )
1206
+ }
1207
+
1208
+ // Add the `selected` class if something's selected and the time matches.
1209
+ if ( isSelected ) {
1210
+ klasses.push( settings.klass.selected )
1211
+ }
1212
+
1213
+ // Add the `highlighted` class if something's highlighted and the time matches.
1214
+ if ( isHighlighted ) {
1215
+ klasses.push( settings.klass.highlighted )
1216
+ }
1217
+
1218
+ // Add the `disabled` class if something's disabled and the object matches.
1219
+ if ( isDisabled ) {
1220
+ klasses.push( settings.klass.disabled )
1221
+ }
1222
+
1223
+ return klasses.join( ' ' )
1224
+ })([ settings.klass.day ]),
1225
+ 'data-pick=' + targetDate.pick + ' ' + _.ariaAttr({
1226
+ role: 'gridcell',
1227
+ label: formattedDate,
1228
+ selected: isSelected && calendar.$node.val() === formattedDate ? true : null,
1229
+ activedescendant: isHighlighted ? true : null,
1230
+ disabled: isDisabled ? true : null
1231
+ })
1232
+ ),
1233
+ '',
1234
+ _.ariaAttr({ role: 'presentation' })
1235
+ ] //endreturn
1236
+ }
1237
+ })
1238
+ ] //endreturn
1239
+ }
1240
+ })
1241
+ ),
1242
+ settings.klass.table,
1243
+ 'id="' + calendar.$node[0].id + '_table' + '" ' + _.ariaAttr({
1244
+ role: 'grid',
1245
+ controls: calendar.$node[0].id,
1246
+ readonly: true
1247
+ })
1248
+ ) +
1249
+
1250
+ // * For Firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
1251
+ _.node(
1252
+ 'div',
1253
+ _.node( 'button', settings.today, settings.klass.buttonToday,
1254
+ 'type=button data-pick=' + nowObject.pick +
1255
+ ( isOpen && !calendar.disabled(nowObject) ? '' : ' disabled' ) + ' ' +
1256
+ _.ariaAttr({ controls: calendar.$node[0].id }) ) +
1257
+ _.node( 'button', settings.clear, settings.klass.buttonClear,
1258
+ 'type=button data-clear=1' +
1259
+ ( isOpen ? '' : ' disabled' ) + ' ' +
1260
+ _.ariaAttr({ controls: calendar.$node[0].id }) ) +
1261
+ _.node('button', settings.close, settings.klass.buttonClose,
1262
+ 'type=button data-close=true ' +
1263
+ ( isOpen ? '' : ' disabled' ) + ' ' +
1264
+ _.ariaAttr({ controls: calendar.$node[0].id }) ),
1265
+ settings.klass.footer
1266
+ ) //endreturn
1267
+ } //DatePicker.prototype.nodes
1268
+
1269
+
1270
+
1271
+
1272
+ /**
1273
+ * The date picker defaults.
1274
+ */
1275
+ DatePicker.defaults = (function( prefix ) {
1276
+
1277
+ return {
1278
+
1279
+ // The title label to use for the month nav buttons
1280
+ labelMonthNext: 'Next month',
1281
+ labelMonthPrev: 'Previous month',
1282
+
1283
+ // The title label to use for the dropdown selectors
1284
+ labelMonthSelect: 'Select a month',
1285
+ labelYearSelect: 'Select a year',
1286
+
1287
+ // Months and weekdays
1288
+ monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
1289
+ monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
1290
+ weekdaysFull: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
1291
+ weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
1292
+
1293
+ // Today and clear
1294
+ today: 'Today',
1295
+ clear: 'Clear',
1296
+ close: 'Close',
1297
+
1298
+ // The format to show on the `input` element
1299
+ format: 'd mmmm, yyyy',
1300
+
1301
+ // Classes
1302
+ klass: {
1303
+
1304
+ table: prefix + 'table',
1305
+
1306
+ header: prefix + 'header',
1307
+
1308
+ navPrev: prefix + 'nav--prev',
1309
+ navNext: prefix + 'nav--next',
1310
+ navDisabled: prefix + 'nav--disabled',
1311
+
1312
+ month: prefix + 'month',
1313
+ year: prefix + 'year',
1314
+
1315
+ selectMonth: prefix + 'select--month',
1316
+ selectYear: prefix + 'select--year',
1317
+
1318
+ weekdays: prefix + 'weekday',
1319
+
1320
+ day: prefix + 'day',
1321
+ disabled: prefix + 'day--disabled',
1322
+ selected: prefix + 'day--selected',
1323
+ highlighted: prefix + 'day--highlighted',
1324
+ now: prefix + 'day--today',
1325
+ infocus: prefix + 'day--infocus',
1326
+ outfocus: prefix + 'day--outfocus',
1327
+
1328
+ footer: prefix + 'footer',
1329
+
1330
+ buttonClear: prefix + 'button--clear',
1331
+ buttonToday: prefix + 'button--today',
1332
+ buttonClose: prefix + 'button--close'
1333
+ }
1334
+ }
1335
+ })( Picker.klasses().picker + '__' )
1336
+
1337
+
1338
+
1339
+
1340
+
1341
+ /**
1342
+ * Extend the picker to add the date picker.
1343
+ */
1344
+ Picker.extend( 'pickadate', DatePicker )
1345
+
1346
+
1347
+ }));
1348
+
1349
+
1350
+
lib/simple-admin-pages/lib/pickadate/picker.js CHANGED
@@ -1,7 +1,1122 @@
1
  /*!
2
- * pickadate.js v3.5.0, 2014/04/13
3
  * By Amsul, http://amsul.ca
4
  * Hosted on http://amsul.github.io/pickadate.js
5
  * Licensed under MIT
6
  */
7
- !function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):this.Picker=a(jQuery)}(function(a){function b(f,g,i,j){function k(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",v.component.nodes(q.open),s.box),s.wrap),s.frame),s.holder)}function l(){t.data(g,v).addClass(s.input).val(t.data("value")?v.get("select",r.format):f.value).on("focus."+q.id+" click."+q.id,o),r.editable||t.on("keydown."+q.id,function(a){var b=a.keyCode,c=/^(8|46)$/.test(b);return 27==b?(v.close(),!1):void((32==b||c||!q.open&&v.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?v.clear().close():v.open()))}),e(f,{haspopup:!0,expanded:!1,readonly:!1,owns:f.id+"_root"+(v._hidden?" "+v._hidden.id:"")})}function m(){v.$root.on({focusin:function(a){v.$root.removeClass(s.focused),a.stopPropagation()},"mousedown click":function(b){var c=b.target;c!=v.$root.children()[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is(":input")||"OPTION"==c.nodeName||(b.preventDefault(),f.focus()))}}).on("click","[data-pick], [data-nav], [data-clear]",function(){var c=a(this),d=c.data(),e=c.hasClass(s.navDisabled)||c.hasClass(s.disabled),g=document.activeElement;g=g&&(g.type||g.href)&&g,(e||g&&!a.contains(v.$root[0],g))&&f.focus(),d.nav&&!e?v.set("highlight",v.component.item.highlight,{nav:d.nav}):b._.isInteger(d.pick)&&!e?v.set("select",d.pick).close(!0):d.clear&&v.clear().close(!0)}),e(v.$root[0],"hidden",!0)}function n(){var b,c;r.hiddenName===!0?(b=f.name+"_hidden",c=f.name,f.name=""):(c=["string"==typeof r.hiddenPrefix?r.hiddenPrefix:"","string"==typeof r.hiddenSuffix?r.hiddenSuffix:"_submit"],c=b=c[0]+f.name+c[1]),v._hidden=a('<input type=hidden name="'+c+'"id="'+b+'"'+(t.data("value")||f.value?' value="'+v.get("select",r.formatSubmit)+'"':"")+">")[0],t.on("change."+q.id,function(){v._hidden.value=f.value?v.get("select",r.formatSubmit):""}).after(v._hidden)}function o(a){a.stopPropagation(),"focus"==a.type&&v.$root.addClass(s.focused),v.open()}if(!f)return b;var p=!1,q={id:f.id||"P"+Math.abs(~~(Math.random()*new Date))},r=i?a.extend(!0,{},i.defaults,j):j||{},s=a.extend({},b.klasses(),r.klass),t=a(f),u=function(){return this.start()},v=u.prototype={constructor:u,$node:t,start:function(){return q&&q.start?v:(q.methods={},q.start=!0,q.open=!1,q.type=f.type,f.autofocus=f==document.activeElement,f.type="text",f.readOnly=!r.editable,f.id=f.id||q.id,v.component=new i(v,r),v.$root=a(b._.node("div",k(),s.picker,'id="'+f.id+'_root"')),m(),r.formatSubmit&&n(),l(),r.container?a(r.container).append(v.$root):t.after(v.$root),v.on({start:v.component.onStart,render:v.component.onRender,stop:v.component.onStop,open:v.component.onOpen,close:v.component.onClose,set:v.component.onSet}).on({start:r.onStart,render:r.onRender,stop:r.onStop,open:r.onOpen,close:r.onClose,set:r.onSet}),p=c(v.$root.children()[0]),f.autofocus&&v.open(),v.trigger("start").trigger("render"))},render:function(a){return a?v.$root.html(k()):v.$root.find("."+s.box).html(v.component.nodes(q.open)),v.trigger("render")},stop:function(){return q.start?(v.close(),v._hidden&&v._hidden.parentNode.removeChild(v._hidden),v.$root.remove(),t.removeClass(s.input).removeData(g),setTimeout(function(){t.off("."+q.id)},0),f.type=q.type,f.readOnly=!1,v.trigger("stop"),q.methods={},q.start=!1,v):v},open:function(c){return q.open?v:(t.addClass(s.active),e(f,"expanded",!0),setTimeout(function(){v.$root.addClass(s.opened),e(v.$root[0],"hidden",!1)},0),c!==!1&&(q.open=!0,p&&a("html").css("overflow","hidden").css("padding-right","+="+d()),t.trigger("focus"),h.on("click."+q.id+" focusin."+q.id,function(a){var b=a.target;b!=f&&b!=document&&3!=a.which&&v.close(b===v.$root.children()[0])}).on("keydown."+q.id,function(c){var d=c.keyCode,e=v.component.key[d],g=c.target;27==d?v.close(!0):g!=f||!e&&13!=d?a.contains(v.$root[0],g)&&13==d&&(c.preventDefault(),g.click()):(c.preventDefault(),e?b._.trigger(v.component.key.go,v,[b._.trigger(e)]):v.$root.find("."+s.highlighted).hasClass(s.disabled)||v.set("select",v.component.item.highlight).close())})),v.trigger("open"))},close:function(b){return b&&(t.off("focus."+q.id).trigger("focus"),setTimeout(function(){t.on("focus."+q.id,o)},0)),t.removeClass(s.active),e(f,"expanded",!1),setTimeout(function(){v.$root.removeClass(s.opened+" "+s.focused),e(v.$root[0],"hidden",!0)},0),q.open?(q.open=!1,p&&a("html").css("overflow","").css("padding-right","-="+d()),h.off("."+q.id),v.trigger("close")):v},clear:function(){return v.set("clear")},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in v.component.item&&(void 0===f&&(f=null),v.component.set(e,f,d)),("select"==e||"clear"==e)&&t.val("clear"==e?"":v.get(e,r.format)).trigger("change");v.render()}return d.muted?v:v.trigger("set",h)},get:function(a,c){return a=a||"value",null!=q[a]?q[a]:"value"==a?f.value:a in v.component.item?"string"==typeof c?b._.trigger(v.component.formats.toString,v.component,[c,v.component.get(a)]):v.component.get(a):void 0},on:function(b,c){var d,e,f=a.isPlainObject(b),g=f?b:{};if(b){f||(g[b]=c);for(d in g)e=g[d],q.methods[d]=q.methods[d]||[],q.methods[d].push(e)}return v},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;namesCount>a;a+=1)b=c[a],b in q.methods&&delete q.methods[b];return v},trigger:function(a,c){var d=q.methods[a];return d&&d.map(function(a){b._.trigger(a,v,[c])}),v}};return new u}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else f(b,c,d)}function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d,f=b[d];c+=null==f?"":e+'="'+b[d]+'"'}return c}var h=a(document);return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(10>a?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1===0},ariaAttr:g},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){var f=a(this);f.data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /*!
2
+ * pickadate.js v3.5.5, 2015/01/6
3
  * By Amsul, http://amsul.ca
4
  * Hosted on http://amsul.github.io/pickadate.js
5
  * Licensed under MIT
6
  */
7
+
8
+ (function ( factory ) {
9
+
10
+ // AMD.
11
+ if ( typeof define == 'function' && define.amd )
12
+ define( 'picker', ['jquery'], factory )
13
+
14
+ // Node.js/browserify.
15
+ else if ( typeof exports == 'object' )
16
+ module.exports = factory( require('jquery') )
17
+
18
+ // Browser globals.
19
+ else this.Picker = factory( jQuery )
20
+
21
+ }(function( $ ) {
22
+
23
+ var $window = $( window )
24
+ var $document = $( document )
25
+ var $html = $( document.documentElement )
26
+
27
+
28
+ /**
29
+ * The picker constructor that creates a blank picker.
30
+ */
31
+ function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
32
+
33
+ // If there’s no element, return the picker constructor.
34
+ if ( !ELEMENT ) return PickerConstructor
35
+
36
+
37
+ var
38
+ IS_DEFAULT_THEME = false,
39
+
40
+
41
+ // The state of the picker.
42
+ STATE = {
43
+ id: ELEMENT.id || 'P' + Math.abs( ~~(Math.random() * new Date()) )
44
+ },
45
+
46
+
47
+ // Merge the defaults and options passed.
48
+ SETTINGS = COMPONENT ? $.extend( true, {}, COMPONENT.defaults, OPTIONS ) : OPTIONS || {},
49
+
50
+
51
+ // Merge the default classes with the settings classes.
52
+ CLASSES = $.extend( {}, PickerConstructor.klasses(), SETTINGS.klass ),
53
+
54
+
55
+ // The element node wrapper into a jQuery object.
56
+ $ELEMENT = $( ELEMENT ),
57
+
58
+
59
+ // Pseudo picker constructor.
60
+ PickerInstance = function() {
61
+ return this.start()
62
+ },
63
+
64
+
65
+ // The picker prototype.
66
+ P = PickerInstance.prototype = {
67
+
68
+ constructor: PickerInstance,
69
+
70
+ $node: $ELEMENT,
71
+
72
+
73
+ /**
74
+ * Initialize everything
75
+ */
76
+ start: function() {
77
+
78
+ // If it’s already started, do nothing.
79
+ if ( STATE && STATE.start ) return P
80
+
81
+
82
+ // Update the picker states.
83
+ STATE.methods = {}
84
+ STATE.start = true
85
+ STATE.open = false
86
+ STATE.type = ELEMENT.type
87
+
88
+
89
+ // Confirm focus state, convert into text input to remove UA stylings,
90
+ // and set as readonly to prevent keyboard popup.
91
+ ELEMENT.autofocus = ELEMENT == getActiveElement()
92
+ ELEMENT.readOnly = !SETTINGS.editable
93
+ ELEMENT.id = ELEMENT.id || STATE.id
94
+ if ( ELEMENT.type != 'text' ) {
95
+ ELEMENT.type = 'text'
96
+ }
97
+
98
+
99
+ // Create a new picker component with the settings.
100
+ P.component = new COMPONENT(P, SETTINGS)
101
+
102
+
103
+ // Create the picker root with a holder and then prepare it.
104
+ P.$root = $( PickerConstructor._.node('div', createWrappedComponent(), CLASSES.picker, 'id="' + ELEMENT.id + '_root" tabindex="0"') )
105
+ prepareElementRoot()
106
+
107
+
108
+ // If there’s a format for the hidden input element, create the element.
109
+ if ( SETTINGS.formatSubmit ) {
110
+ prepareElementHidden()
111
+ }
112
+
113
+
114
+ // Prepare the input element.
115
+ prepareElement()
116
+
117
+
118
+ // Insert the hidden input as specified in the settings.
119
+ if ( SETTINGS.containerHidden ) $( SETTINGS.containerHidden ).append( P._hidden )
120
+ else $ELEMENT.after( P._hidden )
121
+
122
+
123
+ // Insert the root as specified in the settings.
124
+ if ( SETTINGS.container ) $( SETTINGS.container ).append( P.$root )
125
+ else $ELEMENT.after( P.$root )
126
+
127
+
128
+ // Bind the default component and settings events.
129
+ P.on({
130
+ start: P.component.onStart,
131
+ render: P.component.onRender,
132
+ stop: P.component.onStop,
133
+ open: P.component.onOpen,
134
+ close: P.component.onClose,
135
+ set: P.component.onSet
136
+ }).on({
137
+ start: SETTINGS.onStart,
138
+ render: SETTINGS.onRender,
139
+ stop: SETTINGS.onStop,
140
+ open: SETTINGS.onOpen,
141
+ close: SETTINGS.onClose,
142
+ set: SETTINGS.onSet
143
+ })
144
+
145
+
146
+ // Once we’re all set, check the theme in use.
147
+ IS_DEFAULT_THEME = isUsingDefaultTheme( P.$root.children()[ 0 ] )
148
+
149
+
150
+ // If the element has autofocus, open the picker.
151
+ if ( ELEMENT.autofocus ) {
152
+ P.open()
153
+ }
154
+
155
+
156
+ // Trigger queued the “start” and “render” events.
157
+ return P.trigger( 'start' ).trigger( 'render' )
158
+ }, //start
159
+
160
+
161
+ /**
162
+ * Render a new picker
163
+ */
164
+ render: function( entireComponent ) {
165
+
166
+ // Insert a new component holder in the root or box.
167
+ if ( entireComponent ) P.$root.html( createWrappedComponent() )
168
+ else P.$root.find( '.' + CLASSES.box ).html( P.component.nodes( STATE.open ) )
169
+
170
+ // Trigger the queued “render” events.
171
+ return P.trigger( 'render' )
172
+ }, //render
173
+
174
+
175
+ /**
176
+ * Destroy everything
177
+ */
178
+ stop: function() {
179
+
180
+ // If it’s already stopped, do nothing.
181
+ if ( !STATE.start ) return P
182
+
183
+ // Then close the picker.
184
+ P.close()
185
+
186
+ // Remove the hidden field.
187
+ if ( P._hidden ) {
188
+ P._hidden.parentNode.removeChild( P._hidden )
189
+ }
190
+
191
+ // Remove the root.
192
+ P.$root.remove()
193
+
194
+ // Remove the input class, remove the stored data, and unbind
195
+ // the events (after a tick for IE - see `P.close`).
196
+ $ELEMENT.removeClass( CLASSES.input ).removeData( NAME )
197
+ setTimeout( function() {
198
+ $ELEMENT.off( '.' + STATE.id )
199
+ }, 0)
200
+
201
+ // Restore the element state
202
+ ELEMENT.type = STATE.type
203
+ ELEMENT.readOnly = false
204
+
205
+ // Trigger the queued “stop” events.
206
+ P.trigger( 'stop' )
207
+
208
+ // Reset the picker states.
209
+ STATE.methods = {}
210
+ STATE.start = false
211
+
212
+ return P
213
+ }, //stop
214
+
215
+
216
+ /**
217
+ * Open up the picker
218
+ */
219
+ open: function( dontGiveFocus ) {
220
+
221
+ // If it’s already open, do nothing.
222
+ if ( STATE.open ) return P
223
+
224
+ // Add the “active” class.
225
+ $ELEMENT.addClass( CLASSES.active )
226
+ aria( ELEMENT, 'expanded', true )
227
+
228
+ // * A Firefox bug, when `html` has `overflow:hidden`, results in
229
+ // killing transitions :(. So add the “opened” state on the next tick.
230
+ // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
231
+ setTimeout( function() {
232
+
233
+ // Add the “opened” class to the picker root.
234
+ P.$root.addClass( CLASSES.opened )
235
+ aria( P.$root[0], 'hidden', false )
236
+
237
+ }, 0 )
238
+
239
+ // If we have to give focus, bind the element and doc events.
240
+ if ( dontGiveFocus !== false ) {
241
+
242
+ // Set it as open.
243
+ STATE.open = true
244
+
245
+ // Prevent the page from scrolling.
246
+ if ( IS_DEFAULT_THEME ) {
247
+ $html.
248
+ css( 'overflow', 'hidden' ).
249
+ css( 'padding-right', '+=' + getScrollbarWidth() )
250
+ }
251
+
252
+ // Pass focus to the root element’s jQuery object.
253
+ // * Workaround for iOS8 to bring the picker’s root into view.
254
+ P.$root[0].focus()
255
+
256
+ // Bind the document events.
257
+ $document.on( 'click.' + STATE.id + ' focusin.' + STATE.id, function( event ) {
258
+
259
+ var target = event.target
260
+
261
+ // If the target of the event is not the element, close the picker picker.
262
+ // * Don’t worry about clicks or focusins on the root because those don’t bubble up.
263
+ // Also, for Firefox, a click on an `option` element bubbles up directly
264
+ // to the doc. So make sure the target wasn't the doc.
265
+ // * In Firefox stopPropagation() doesn’t prevent right-click events from bubbling,
266
+ // which causes the picker to unexpectedly close when right-clicking it. So make
267
+ // sure the event wasn’t a right-click.
268
+ if ( target != ELEMENT && target != document && event.which != 3 ) {
269
+
270
+ // If the target was the holder that covers the screen,
271
+ // keep the element focused to maintain tabindex.
272
+ P.close( target === P.$root.children()[0] )
273
+ }
274
+
275
+ }).on( 'keydown.' + STATE.id, function( event ) {
276
+
277
+ var
278
+ // Get the keycode.
279
+ keycode = event.keyCode,
280
+
281
+ // Translate that to a selection change.
282
+ keycodeToMove = P.component.key[ keycode ],
283
+
284
+ // Grab the target.
285
+ target = event.target
286
+
287
+
288
+ // On escape, close the picker and give focus.
289
+ if ( keycode == 27 ) {
290
+ P.close( true )
291
+ }
292
+
293
+
294
+ // Check if there is a key movement or “enter” keypress on the element.
295
+ else if ( target == P.$root[0] && ( keycodeToMove || keycode == 13 ) ) {
296
+
297
+ // Prevent the default action to stop page movement.
298
+ event.preventDefault()
299
+
300
+ // Trigger the key movement action.
301
+ if ( keycodeToMove ) {
302
+ PickerConstructor._.trigger( P.component.key.go, P, [ PickerConstructor._.trigger( keycodeToMove ) ] )
303
+ }
304
+
305
+ // On “enter”, if the highlighted item isn’t disabled, set the value and close.
306
+ else if ( !P.$root.find( '.' + CLASSES.highlighted ).hasClass( CLASSES.disabled ) ) {
307
+ P.set( 'select', P.component.item.highlight ).close()
308
+ }
309
+ }
310
+
311
+
312
+ // If the target is within the root and “enter” is pressed,
313
+ // prevent the default action and trigger a click on the target instead.
314
+ else if ( $.contains( P.$root[0], target ) && keycode == 13 ) {
315
+ event.preventDefault()
316
+ target.click()
317
+ }
318
+ })
319
+ }
320
+
321
+ // Trigger the queued “open” events.
322
+ return P.trigger( 'open' )
323
+ }, //open
324
+
325
+
326
+ /**
327
+ * Close the picker
328
+ */
329
+ close: function( giveFocus ) {
330
+
331
+ // If we need to give focus, do it before changing states.
332
+ if ( giveFocus ) {
333
+ // ....ah yes! It would’ve been incomplete without a crazy workaround for IE :|
334
+ // The focus is triggered *after* the close has completed - causing it
335
+ // to open again. So unbind and rebind the event at the next tick.
336
+ P.$root.off( 'focus.toOpen' )[0].focus()
337
+ setTimeout( function() {
338
+ P.$root.on( 'focus.toOpen', handleFocusToOpenEvent )
339
+ }, 0 )
340
+ }
341
+
342
+ // Remove the “active” class.
343
+ $ELEMENT.removeClass( CLASSES.active )
344
+ aria( ELEMENT, 'expanded', false )
345
+
346
+ // * A Firefox bug, when `html` has `overflow:hidden`, results in
347
+ // killing transitions :(. So remove the “opened” state on the next tick.
348
+ // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
349
+ setTimeout( function() {
350
+
351
+ // Remove the “opened” and “focused” class from the picker root.
352
+ P.$root.removeClass( CLASSES.opened + ' ' + CLASSES.focused )
353
+ aria( P.$root[0], 'hidden', true )
354
+
355
+ }, 0 )
356
+
357
+ // If it’s already closed, do nothing more.
358
+ if ( !STATE.open ) return P
359
+
360
+ // Set it as closed.
361
+ STATE.open = false
362
+
363
+ // Allow the page to scroll.
364
+ if ( IS_DEFAULT_THEME ) {
365
+ $html.
366
+ css( 'overflow', '' ).
367
+ css( 'padding-right', '-=' + getScrollbarWidth() )
368
+ }
369
+
370
+ // Unbind the document events.
371
+ $document.off( '.' + STATE.id )
372
+
373
+ // Trigger the queued “close” events.
374
+ return P.trigger( 'close' )
375
+ }, //close
376
+
377
+
378
+ /**
379
+ * Clear the values
380
+ */
381
+ clear: function( options ) {
382
+ return P.set( 'clear', null, options )
383
+ }, //clear
384
+
385
+
386
+ /**
387
+ * Set something
388
+ */
389
+ set: function( thing, value, options ) {
390
+
391
+ var thingItem, thingValue,
392
+ thingIsObject = $.isPlainObject( thing ),
393
+ thingObject = thingIsObject ? thing : {}
394
+
395
+ // Make sure we have usable options.
396
+ options = thingIsObject && $.isPlainObject( value ) ? value : options || {}
397
+
398
+ if ( thing ) {
399
+
400
+ // If the thing isn’t an object, make it one.
401
+ if ( !thingIsObject ) {
402
+ thingObject[ thing ] = value
403
+ }
404
+
405
+ // Go through the things of items to set.
406
+ for ( thingItem in thingObject ) {
407
+
408
+ // Grab the value of the thing.
409
+ thingValue = thingObject[ thingItem ]
410
+
411
+ // First, if the item exists and there’s a value, set it.
412
+ if ( thingItem in P.component.item ) {
413
+ if ( thingValue === undefined ) thingValue = null
414
+ P.component.set( thingItem, thingValue, options )
415
+ }
416
+
417
+ // Then, check to update the element value and broadcast a change.
418
+ if ( thingItem == 'select' || thingItem == 'clear' ) {
419
+ $ELEMENT.
420
+ val( thingItem == 'clear' ? '' : P.get( thingItem, SETTINGS.format ) ).
421
+ trigger( 'change' )
422
+ }
423
+ }
424
+
425
+ // Render a new picker.
426
+ P.render()
427
+ }
428
+
429
+ // When the method isn’t muted, trigger queued “set” events and pass the `thingObject`.
430
+ return options.muted ? P : P.trigger( 'set', thingObject )
431
+ }, //set
432
+
433
+
434
+ /**
435
+ * Get something
436
+ */
437
+ get: function( thing, format ) {
438
+
439
+ // Make sure there’s something to get.
440
+ thing = thing || 'value'
441
+
442
+ // If a picker state exists, return that.
443
+ if ( STATE[ thing ] != null ) {
444
+ return STATE[ thing ]
445
+ }
446
+
447
+ // Return the submission value, if that.
448
+ if ( thing == 'valueSubmit' ) {
449
+ if ( P._hidden ) {
450
+ return P._hidden.value
451
+ }
452
+ thing = 'value'
453
+ }
454
+
455
+ // Return the value, if that.
456
+ if ( thing == 'value' ) {
457
+ return ELEMENT.value
458
+ }
459
+
460
+ // Check if a component item exists, return that.
461
+ if ( thing in P.component.item ) {
462
+ if ( typeof format == 'string' ) {
463
+ var thingValue = P.component.get( thing )
464
+ return thingValue ?
465
+ PickerConstructor._.trigger(
466
+ P.component.formats.toString,
467
+ P.component,
468
+ [ format, thingValue ]
469
+ ) : ''
470
+ }
471
+ return P.component.get( thing )
472
+ }
473
+ }, //get
474
+
475
+
476
+
477
+ /**
478
+ * Bind events on the things.
479
+ */
480
+ on: function( thing, method, internal ) {
481
+
482
+ var thingName, thingMethod,
483
+ thingIsObject = $.isPlainObject( thing ),
484
+ thingObject = thingIsObject ? thing : {}
485
+
486
+ if ( thing ) {
487
+
488
+ // If the thing isn’t an object, make it one.
489
+ if ( !thingIsObject ) {
490
+ thingObject[ thing ] = method
491
+ }
492
+
493
+ // Go through the things to bind to.
494
+ for ( thingName in thingObject ) {
495
+
496
+ // Grab the method of the thing.
497
+ thingMethod = thingObject[ thingName ]
498
+
499
+ // If it was an internal binding, prefix it.
500
+ if ( internal ) {
501
+ thingName = '_' + thingName
502
+ }
503
+
504
+ // Make sure the thing methods collection exists.
505
+ STATE.methods[ thingName ] = STATE.methods[ thingName ] || []
506
+
507
+ // Add the method to the relative method collection.
508
+ STATE.methods[ thingName ].push( thingMethod )
509
+ }
510
+ }
511
+
512
+ return P
513
+ }, //on
514
+
515
+
516
+
517
+ /**
518
+ * Unbind events on the things.
519
+ */
520
+ off: function() {
521
+ var i, thingName,
522
+ names = arguments;
523
+ for ( i = 0, namesCount = names.length; i < namesCount; i += 1 ) {
524
+ thingName = names[i]
525
+ if ( thingName in STATE.methods ) {
526
+ delete STATE.methods[thingName]
527
+ }
528
+ }
529
+ return P
530
+ },
531
+
532
+
533
+ /**
534
+ * Fire off method events.
535
+ */
536
+ trigger: function( name, data ) {
537
+ var _trigger = function( name ) {
538
+ var methodList = STATE.methods[ name ]
539
+ if ( methodList ) {
540
+ methodList.map( function( method ) {
541
+ PickerConstructor._.trigger( method, P, [ data ] )
542
+ })
543
+ }
544
+ }
545
+ _trigger( '_' + name )
546
+ _trigger( name )
547
+ return P
548
+ } //trigger
549
+ } //PickerInstance.prototype
550
+
551
+
552
+ /**
553
+ * Wrap the picker holder components together.
554
+ */
555
+ function createWrappedComponent() {
556
+
557
+ // Create a picker wrapper holder
558
+ return PickerConstructor._.node( 'div',
559
+
560
+ // Create a picker wrapper node
561
+ PickerConstructor._.node( 'div',
562
+
563
+ // Create a picker frame
564
+ PickerConstructor._.node( 'div',
565
+
566
+ // Create a picker box node
567
+ PickerConstructor._.node( 'div',
568
+
569
+ // Create the components nodes.
570
+ P.component.nodes( STATE.open ),
571
+
572
+ // The picker box class
573
+ CLASSES.box
574
+ ),
575
+
576
+ // Picker wrap class
577
+ CLASSES.wrap
578
+ ),
579
+
580
+ // Picker frame class
581
+ CLASSES.frame
582
+ ),
583
+
584
+ // Picker holder class
585
+ CLASSES.holder
586
+ ) //endreturn
587
+ } //createWrappedComponent
588
+
589
+
590
+
591
+ /**
592
+ * Prepare the input element with all bindings.
593
+ */
594
+ function prepareElement() {
595
+
596
+ $ELEMENT.
597
+
598
+ // Store the picker data by component name.
599
+ data(NAME, P).
600
+
601
+ // Add the “input” class name.
602
+ addClass(CLASSES.input).
603
+
604
+ // Remove the tabindex.
605
+ attr('tabindex', -1).
606
+
607
+ // If there’s a `data-value`, update the value of the element.
608
+ val( $ELEMENT.data('value') ?
609
+ P.get('select', SETTINGS.format) :
610
+ ELEMENT.value
611
+ )
612
+
613
+
614
+ // Only bind keydown events if the element isn’t editable.
615
+ if ( !SETTINGS.editable ) {
616
+
617
+ $ELEMENT.
618
+
619
+ // On focus/click, focus onto the root to open it up.
620
+ on( 'focus.' + STATE.id + ' click.' + STATE.id, function( event ) {
621
+ event.preventDefault()
622
+ P.$root[0].focus()
623
+ }).
624
+
625
+ // Handle keyboard event based on the picker being opened or not.
626
+ on( 'keydown.' + STATE.id, handleKeydownEvent )
627
+ }
628
+
629
+
630
+ // Update the aria attributes.
631
+ aria(ELEMENT, {
632
+ haspopup: true,
633
+ expanded: false,
634
+ readonly: false,
635
+ owns: ELEMENT.id + '_root'
636
+ })
637
+ }
638
+
639
+
640
+ /**
641
+ * Prepare the root picker element with all bindings.
642
+ */
643
+ function prepareElementRoot() {
644
+
645
+ P.$root.
646
+
647
+ on({
648
+
649
+ // For iOS8.
650
+ keydown: handleKeydownEvent,
651
+
652
+ // When something within the root is focused, stop from bubbling
653
+ // to the doc and remove the “focused” state from the root.
654
+ focusin: function( event ) {
655
+ P.$root.removeClass( CLASSES.focused )
656
+ event.stopPropagation()
657
+ },
658
+
659
+ // When something within the root holder is clicked, stop it
660
+ // from bubbling to the doc.
661
+ 'mousedown click': function( event ) {
662
+
663
+ var target = event.target
664
+
665
+ // Make sure the target isn’t the root holder so it can bubble up.
666
+ if ( target != P.$root.children()[ 0 ] ) {
667
+
668
+ event.stopPropagation()
669
+
670
+ // * For mousedown events, cancel the default action in order to
671
+ // prevent cases where focus is shifted onto external elements
672
+ // when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
673
+ // Also, for Firefox, don’t prevent action on the `option` element.
674
+ if ( event.type == 'mousedown' && !$( target ).is( 'input, select, textarea, button, option' )) {
675
+
676
+ event.preventDefault()
677
+
678
+ // Re-focus onto the root so that users can click away
679
+ // from elements focused within the picker.
680
+ P.$root[0].focus()
681
+ }
682
+ }
683
+ }
684
+ }).
685
+
686
+ // Add/remove the “target” class on focus and blur.
687
+ on({
688
+ focus: function() {
689
+ $ELEMENT.addClass( CLASSES.target )
690
+ },
691
+ blur: function() {
692
+ $ELEMENT.removeClass( CLASSES.target )
693
+ }
694
+ }).
695
+
696
+ // Open the picker and adjust the root “focused” state
697
+ on( 'focus.toOpen', handleFocusToOpenEvent ).
698
+
699
+ // If there’s a click on an actionable element, carry out the actions.
700
+ on( 'click', '[data-pick], [data-nav], [data-clear], [data-close]', function() {
701
+
702
+ var $target = $( this ),
703
+ targetData = $target.data(),
704
+ targetDisabled = $target.hasClass( CLASSES.navDisabled ) || $target.hasClass( CLASSES.disabled ),
705
+
706
+ // * For IE, non-focusable elements can be active elements as well
707
+ // (http://stackoverflow.com/a/2684561).
708
+ activeElement = getActiveElement()
709
+ activeElement = activeElement && ( activeElement.type || activeElement.href )
710
+
711
+ // If it’s disabled or nothing inside is actively focused, re-focus the element.
712
+ if ( targetDisabled || activeElement && !$.contains( P.$root[0], activeElement ) ) {
713
+ P.$root[0].focus()
714
+ }
715
+
716
+ // If something is superficially changed, update the `highlight` based on the `nav`.
717
+ if ( !targetDisabled && targetData.nav ) {
718
+ P.set( 'highlight', P.component.item.highlight, { nav: targetData.nav } )
719
+ }
720
+
721
+ // If something is picked, set `select` then close with focus.
722
+ else if ( !targetDisabled && 'pick' in targetData ) {
723
+ P.set( 'select', targetData.pick ).close( true )
724
+ }
725
+
726
+ // If a “clear” button is pressed, empty the values and close with focus.
727
+ else if ( targetData.clear ) {
728
+ P.clear().close( true )
729
+ }
730
+
731
+ else if ( targetData.close ) {
732
+ P.close( true )
733
+ }
734
+
735
+ }) //P.$root
736
+
737
+ aria( P.$root[0], 'hidden', true )
738
+ }
739
+
740
+
741
+ /**
742
+ * Prepare the hidden input element along with all bindings.
743
+ */
744
+ function prepareElementHidden() {
745
+
746
+ var name
747
+
748
+ if ( SETTINGS.hiddenName === true ) {
749
+ name = ELEMENT.name
750
+ ELEMENT.name = ''
751
+ }
752
+ else {
753
+ name = [
754
+ typeof SETTINGS.hiddenPrefix == 'string' ? SETTINGS.hiddenPrefix : '',
755
+ typeof SETTINGS.hiddenSuffix == 'string' ? SETTINGS.hiddenSuffix : '_submit'
756
+ ]
757
+ name = name[0] + ELEMENT.name + name[1]
758
+ }
759
+
760
+ P._hidden = $(
761
+ '<input ' +
762
+ 'type=hidden ' +
763
+
764
+ // Create the name using the original input’s with a prefix and suffix.
765
+ 'name="' + name + '"' +
766
+
767
+ // If the element has a value, set the hidden value as well.
768
+ (
769
+ $ELEMENT.data('value') || ELEMENT.value ?
770
+ ' value="' + P.get('select', SETTINGS.formatSubmit) + '"' :
771
+ ''
772
+ ) +
773
+ '>'
774
+ )[0]
775
+
776
+ $ELEMENT.
777
+
778
+ // If the value changes, update the hidden input with the correct format.
779
+ on('change.' + STATE.id, function() {
780
+ P._hidden.value = ELEMENT.value ?
781
+ P.get('select', SETTINGS.formatSubmit) :
782
+ ''
783
+ })
784
+ }
785
+
786
+
787
+ // For iOS8.
788
+ function handleKeydownEvent( event ) {
789
+
790
+ var keycode = event.keyCode,
791
+
792
+ // Check if one of the delete keys was pressed.
793
+ isKeycodeDelete = /^(8|46)$/.test(keycode)
794
+
795
+ // For some reason IE clears the input value on “escape”.
796
+ if ( keycode == 27 ) {
797
+ P.close()
798
+ return false
799
+ }
800
+
801
+ // Check if `space` or `delete` was pressed or the picker is closed with a key movement.
802
+ if ( keycode == 32 || isKeycodeDelete || !STATE.open && P.component.key[keycode] ) {
803
+
804
+ // Prevent it from moving the page and bubbling to doc.
805
+ event.preventDefault()
806
+ event.stopPropagation()
807
+
808
+ // If `delete` was pressed, clear the values and close the picker.
809
+ // Otherwise open the picker.
810
+ if ( isKeycodeDelete ) { P.clear().close() }
811
+ else { P.open() }
812
+ }
813
+ }
814
+
815
+
816
+ // Separated for IE
817
+ function handleFocusToOpenEvent( event ) {
818
+
819
+ // Stop the event from propagating to the doc.
820
+ event.stopPropagation()
821
+
822
+ // Add the “focused” class to the root.
823
+ P.$root.addClass( CLASSES.focused )
824
+
825
+ // And then finally open the picker.
826
+ P.open()
827
+ }
828
+
829
+
830
+ // Return a new picker instance.
831
+ return new PickerInstance()
832
+ } //PickerConstructor
833
+
834
+
835
+
836
+ /**
837
+ * The default classes and prefix to use for the HTML classes.
838
+ */
839
+ PickerConstructor.klasses = function( prefix ) {
840
+ prefix = prefix || 'picker'
841
+ return {
842
+
843
+ picker: prefix,
844
+ opened: prefix + '--opened',
845
+ focused: prefix + '--focused',
846
+
847
+ input: prefix + '__input',
848
+ active: prefix + '__input--active',
849
+ target: prefix + '__input--target',
850
+
851
+ holder: prefix + '__holder',
852
+
853
+ frame: prefix + '__frame',
854
+ wrap: prefix + '__wrap',
855
+
856
+ box: prefix + '__box'
857
+ }
858
+ } //PickerConstructor.klasses
859
+
860
+
861
+
862
+ /**
863
+ * Check if the default theme is being used.
864
+ */
865
+ function isUsingDefaultTheme( element ) {
866
+
867
+ var theme,
868
+ prop = 'position'
869
+
870
+ // For IE.
871
+ if ( element.currentStyle ) {
872
+ theme = element.currentStyle[prop]
873
+ }
874
+
875
+ // For normal browsers.
876
+ else if ( window.getComputedStyle ) {
877
+ theme = getComputedStyle( element )[prop]
878
+ }
879
+
880
+ return theme == 'fixed'
881
+ }
882
+
883
+
884
+
885
+ /**
886
+ * Get the width of the browser’s scrollbar.
887
+ * Taken from: https://github.com/VodkaBears/Remodal/blob/master/src/jquery.remodal.js
888
+ */
889
+ function getScrollbarWidth() {
890
+
891
+ if ( $html.height() <= $window.height() ) {
892
+ return 0
893
+ }
894
+
895
+ var $outer = $( '<div style="visibility:hidden;width:100px" />' ).
896
+ appendTo( 'body' )
897
+
898
+ // Get the width without scrollbars.
899
+ var widthWithoutScroll = $outer[0].offsetWidth
900
+
901
+ // Force adding scrollbars.
902
+ $outer.css( 'overflow', 'scroll' )
903
+
904
+ // Add the inner div.
905
+ var $inner = $( '<div style="width:100%" />' ).appendTo( $outer )
906
+
907
+ // Get the width with scrollbars.
908
+ var widthWithScroll = $inner[0].offsetWidth
909
+
910
+ // Remove the divs.
911
+ $outer.remove()
912
+
913
+ // Return the difference between the widths.
914
+ return widthWithoutScroll - widthWithScroll
915
+ }
916
+
917
+
918
+
919
+ /**
920
+ * PickerConstructor helper methods.
921
+ */
922
+ PickerConstructor._ = {
923
+
924
+ /**
925
+ * Create a group of nodes. Expects:
926
+ * `
927
+ {
928
+ min: {Integer},
929
+ max: {Integer},
930
+ i: {Integer},
931
+ node: {String},
932
+ item: {Function}
933
+ }
934
+ * `
935
+ */
936
+ group: function( groupObject ) {
937
+
938
+ var
939
+ // Scope for the looped object
940
+ loopObjectScope,
941
+
942
+ // Create the nodes list
943
+ nodesList = '',
944
+
945
+ // The counter starts from the `min`
946
+ counter = PickerConstructor._.trigger( groupObject.min, groupObject )
947
+
948
+
949
+ // Loop from the `min` to `max`, incrementing by `i`
950
+ for ( ; counter <= PickerConstructor._.trigger( groupObject.max, groupObject, [ counter ] ); counter += groupObject.i ) {
951
+
952
+ // Trigger the `item` function within scope of the object
953
+ loopObjectScope = PickerConstructor._.trigger( groupObject.item, groupObject, [ counter ] )
954
+
955
+ // Splice the subgroup and create nodes out of the sub nodes
956
+ nodesList += PickerConstructor._.node(
957
+ groupObject.node,
958
+ loopObjectScope[ 0 ], // the node
959
+ loopObjectScope[ 1 ], // the classes
960
+ loopObjectScope[ 2 ] // the attributes
961
+ )
962
+ }
963
+
964
+ // Return the list of nodes
965
+ return nodesList
966
+ }, //group
967
+
968
+
969
+ /**
970
+ * Create a dom node string
971
+ */
972
+ node: function( wrapper, item, klass, attribute ) {
973
+
974
+ // If the item is false-y, just return an empty string
975
+ if ( !item ) return ''
976
+
977
+ // If the item is an array, do a join
978
+ item = $.isArray( item ) ? item.join( '' ) : item
979
+
980
+ // Check for the class
981
+ klass = klass ? ' class="' + klass + '"' : ''
982
+
983
+ // Check for any attributes
984
+ attribute = attribute ? ' ' + attribute : ''
985
+
986
+ // Return the wrapped item
987
+ return '<' + wrapper + klass + attribute + '>' + item + '</' + wrapper + '>'
988
+ }, //node
989
+
990
+
991
+ /**
992
+ * Lead numbers below 10 with a zero.
993
+ */
994
+ lead: function( number ) {
995
+ return ( number < 10 ? '0': '' ) + number
996
+ },
997
+
998
+
999
+ /**
1000
+ * Trigger a function otherwise return the value.
1001
+ */
1002
+ trigger: function( callback, scope, args ) {
1003
+ return typeof callback == 'function' ? callback.apply( scope, args || [] ) : callback
1004
+ },
1005
+
1006
+
1007
+ /**
1008
+ * If the second character is a digit, length is 2 otherwise 1.
1009
+ */
1010
+ digits: function( string ) {
1011
+ return ( /\d/ ).test( string[ 1 ] ) ? 2 : 1
1012
+ },
1013
+
1014
+
1015
+ /**
1016
+ * Tell if something is a date object.
1017
+ */
1018
+ isDate: function( value ) {
1019
+ return {}.toString.call( value ).indexOf( 'Date' ) > -1 && this.isInteger( value.getDate() )
1020
+ },
1021
+
1022
+
1023
+ /**
1024
+ * Tell if something is an integer.
1025
+ */
1026
+ isInteger: function( value ) {
1027
+ return {}.toString.call( value ).indexOf( 'Number' ) > -1 && value % 1 === 0
1028
+ },
1029
+
1030
+
1031
+ /**
1032
+ * Create ARIA attribute strings.
1033
+ */
1034
+ ariaAttr: ariaAttr
1035
+ } //PickerConstructor._
1036
+
1037
+
1038
+
1039
+ /**
1040
+ * Extend the picker with a component and defaults.
1041
+ */
1042
+ PickerConstructor.extend = function( name, Component ) {
1043
+
1044
+ // Extend jQuery.
1045
+ $.fn[ name ] = function( options, action ) {
1046
+
1047
+ // Grab the component data.
1048
+ var componentData = this.data( name )
1049
+
1050
+ // If the picker is requested, return the data object.
1051
+ if ( options == 'picker' ) {
1052
+ return componentData
1053
+ }
1054
+
1055
+ // If the component data exists and `options` is a string, carry out the action.
1056
+ if ( componentData && typeof options == 'string' ) {
1057
+ return PickerConstructor._.trigger( componentData[ options ], componentData, [ action ] )
1058
+ }
1059
+
1060
+ // Otherwise go through each matched element and if the component
1061
+ // doesn’t exist, create a new picker using `this` element
1062
+ // and merging the defaults and options with a deep copy.
1063
+ return this.each( function() {
1064
+ var $this = $( this )
1065
+ if ( !$this.data( name ) ) {
1066
+ new PickerConstructor( this, name, Component, options )
1067
+ }
1068
+ })
1069
+ }
1070
+
1071
+ // Set the defaults.
1072
+ $.fn[ name ].defaults = Component.defaults
1073
+ } //PickerConstructor.extend
1074
+
1075
+
1076
+
1077
+ function aria(element, attribute, value) {
1078
+ if ( $.isPlainObject(attribute) ) {
1079
+ for ( var key in attribute ) {
1080
+ ariaSet(element, key, attribute[key])
1081
+ }
1082
+ }
1083
+ else {
1084
+ ariaSet(element, attribute, value)
1085
+ }
1086
+ }
1087
+ function ariaSet(element, attribute, value) {
1088
+ element.setAttribute(
1089
+ (attribute == 'role' ? '' : 'aria-') + attribute,
1090
+ value
1091
+ )
1092
+ }
1093
+ function ariaAttr(attribute, data) {
1094
+ if ( !$.isPlainObject(attribute) ) {
1095
+ attribute = { attribute: data }
1096
+ }
1097
+ data = ''
1098
+ for ( var key in attribute ) {
1099
+ var attr = (key == 'role' ? '' : 'aria-') + key,
1100
+ attrVal = attribute[key]
1101
+ data += attrVal == null ? '' : attr + '="' + attribute[key] + '"'
1102
+ }
1103
+ return data
1104
+ }
1105
+
1106
+ // IE8 bug throws an error for activeElements within iframes.
1107
+ function getActiveElement() {
1108
+ try {
1109
+ return document.activeElement
1110
+ } catch ( err ) { }
1111
+ }
1112
+
1113
+
1114
+
1115
+ // Expose the picker constructor.
1116
+ return PickerConstructor
1117
+
1118
+
1119
+ }));
1120
+
1121
+
1122
+
lib/simple-admin-pages/lib/pickadate/picker.time.js CHANGED
@@ -1,5 +1,1010 @@
1
  /*!
2
- * Time picker for pickadate.js v3.5.0
3
  * http://amsul.github.io/pickadate.js/time.htm
4
  */
5
- !function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0].value,e=a.$node.data("value"),f=e||d,g=e?b.formatSubmit:b.format;c.settings=b,c.$node=a.$node,c.queue={interval:"i",min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse create validate",view:"parse create validate",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.interval=b.interval||30,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),f?c.set("select",f,{format:g,fromValue:!!d}):c.set("select",null).set("highlight",c.item.now),c.key={40:1,38:-1,39:1,37:-1,go:function(a){c.set("highlight",c.item.highlight.pick+a*c.item.interval,{interval:a*c.item.interval}),this.render()}},a.on("render",function(){var c=a.$root.children(),d=c.find("."+b.klass.viewset);d.length&&(c[0].scrollTop=~~d.position().top-2*d[0].clientHeight)}).on("open",function(){a.$root.find("button").attr("disabled",!1)}).on("close",function(){a.$root.find("button").attr("disabled",!0)})}var d=24,e=60,f=12,g=d*e,h=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):"interval"==a?d.set("min",e.min,c).set("max",e.max,c):a.match(/^(flip|min|max|disable|enable)$/)&&("min"==a&&d.set("max",e.max,c),e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,f){var i=this;return c=void 0===c?a:c,h.isDate(c)&&(c=[c.getHours(),c.getMinutes()]),b.isPlainObject(c)&&h.isInteger(c.pick)?c=c.pick:b.isArray(c)?c=+c[0]*e+ +c[1]:h.isInteger(c)||(c=i.now(a,c,f)),"max"==a&&c<i.item.min.pick&&(c+=g),"min"!=a&&"max"!=a&&(c-i.item.min.pick)%i.item.interval!==0&&(c+=i.item.interval),c=i.normalize(a,c,f),{hour:~~(d+c/e)%d,mins:(e+c%e)%e,time:(g+c)%g,pick:c}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||h.isDate(a)?d.create(a):a};return h.isInteger(a)||(a=e(a)),h.isInteger(c)||(c=e(c)),h.isInteger(a)&&b.isPlainObject(c)?a=[c.hour,c.mins+a*d.settings.interval]:h.isInteger(c)&&b.isPlainObject(a)&&(c=[a.hour,a.mins+c*d.settings.interval]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b){var c,d=this.item.interval,f=new Date,g=f.getHours()*e+f.getMinutes(),i=h.isInteger(b);return g-=g%d,c=0>b&&-d>=d*b+g,g+="min"==a&&c?0:d,i&&(g+=d*(c&&"max"!=a?b+1:b)),g},c.prototype.normalize=function(a,b){var c=this.item.interval,d=this.item.min&&this.item.min.pick||0;return b-="min"==a?0:(b-d)%c},c.prototype.measure=function(a,c,f){var g=this;return c?c===!0||h.isInteger(c)?c=g.now(a,c,f):b.isPlainObject(c)&&h.isInteger(c.pick)&&(c=g.normalize(a,c.pick,f)):c="min"==a?[0,0]:[d-1,e-1],c},c.prototype.validate=function(a,b,c){var d=this,e=c&&c.interval?c.interval:d.item.interval;return d.disabled(b)&&(b=d.shift(b,e)),b=d.scope(b),d.disabled(b)&&(b=d.shift(b,-1*e)),b},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return h.isInteger(d)?a.hour==d:b.isArray(d)||h.isDate(d)?a.pick==c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[2]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.shift=function(a,b){var c=this,d=c.item.min.pick,e=c.item.max.pick;for(b=b||c.item.interval;c.disabled(a)&&(a=c.create(a.pick+=b),!(a.pick<=d||a.pick>=e)););return a},c.prototype.scope=function(a){var b=this.item.min.pick,c=this.item.max.pick;return this.create(a.pick>c?c:a.pick<b?b:a)},c.prototype.parse=function(a,b,c){var d,f,g,i,j,k=this,l={};if(!b||"string"!=typeof b)return b;c&&c.format||(c=c||{},c.format=k.settings.format),k.formats.toArray(c.format).map(function(a){var c,d=k.formats[a],e=d?h.trigger(d,k,[b,l]):a.replace(/^!/,"").length;d&&(c=b.substr(0,e),l[a]=c.match(/^\d+$/)?+c:c),b=b.substr(e)});for(i in l)j=l[i],h.isInteger(j)?i.match(/^(h|hh)$/i)?(d=j,("h"==i||"hh"==i)&&(d%=12)):"i"==i&&(f=j):i.match(/^a$/i)&&j.match(/^p/i)&&("h"in l||"hh"in l)&&(g=!0);return(g?d+12:d)*e+f},c.prototype.formats={h:function(a,b){return a?h.digits(a):b.hour%f||f},hh:function(a,b){return a?2:h.lead(b.hour%f||f)},H:function(a,b){return a?h.digits(a):""+b.hour%24},HH:function(a,b){return a?h.digits(a):h.lead(b.hour%24)},i:function(a,b){return a?2:h.lead(b.mins)},a:function(a,b){return a?4:g/2>b.time%g?"a.m.":"p.m."},A:function(a,b){return a?2:g/2>b.time%g?"AM":"PM"},toArray:function(a){return a.split(/(h{1,2}|H{1,2}|i|a|A|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return h.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}},c.prototype.isTimeExact=function(a,c){var d=this;return h.isInteger(a)&&h.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(h.isDate(a)||b.isArray(a))&&(h.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isTimeExact(a.from,c.from)&&d.isTimeExact(a.to,c.to):!1},c.prototype.isTimeOverlap=function(a,c){var d=this;return h.isInteger(a)&&(h.isDate(c)||b.isArray(c))?a===d.create(c).hour:h.isInteger(c)&&(h.isDate(a)||b.isArray(a))?c===d.create(a).hour:b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,f=0;f<e.length;f+=1)if(d.isTimeExact(a,e[f])){c=!0;break}c||(h.isInteger(a)||h.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,f=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,g,i,j;for(i=0;f>i;i+=1){if(g=e[i],d.isTimeExact(g,a)){c=e[i]=null,j=!0;break}if(d.isTimeOverlap(g,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[2]||c.push("inverted")):h.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;f>i;i+=1)if(d.isTimeExact(e[i],a)){e[i]=null;break}if(j)for(i=0;f>i;i+=1)if(d.isTimeOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.i=function(a,b){return h.isInteger(b)&&b>0?b:this.item.interval},c.prototype.nodes=function(a){var b=this,c=b.settings,d=b.item.select,e=b.item.highlight,f=b.item.view,g=b.item.disable;return h.node("ul",h.group({min:b.item.min.pick,max:b.item.max.pick,i:b.item.interval,node:"li",item:function(a){a=b.create(a);var i=a.pick,j=d&&d.pick==i,k=e&&e.pick==i,l=g&&b.disabled(a);return[h.trigger(b.formats.toString,b,[h.trigger(c.formatLabel,b,[a])||c.format,a]),function(a){return j&&a.push(c.klass.selected),k&&a.push(c.klass.highlighted),f&&f.pick==i&&a.push(c.klass.viewset),l&&a.push(c.klass.disabled),a.join(" ")}([c.klass.listItem]),"data-pick="+a.pick+" "+h.ariaAttr({role:"option",selected:j&&b.$node.val()===h.trigger(b.formats.toString,b,[c.format,a])?!0:null,activedescendant:k?!0:null,disabled:l?!0:null})]}})+h.node("li",h.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+h.ariaAttr({controls:b.$node[0].id})),"",h.ariaAttr({role:"presentation"})),c.klass.list,h.ariaAttr({role:"listbox",controls:b.$node[0].id}))},c.defaults=function(a){return{clear:"Clear",format:"h:i A",interval:30,klass:{picker:a+" "+a+"--time",holder:a+"__holder",list:a+"__list",listItem:a+"__list-item",disabled:a+"__list-item--disabled",selected:a+"__list-item--selected",highlighted:a+"__list-item--highlighted",viewset:a+"__list-item--viewset",now:a+"__list-item--now",buttonClear:a+"__button--clear"}}}(a.klasses().picker),a.extend("pickatime",c)});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /*!
2
+ * Time picker for pickadate.js v3.5.5
3
  * http://amsul.github.io/pickadate.js/time.htm
4
  */
5
+
6
+ (function ( factory ) {
7
+
8
+ // AMD.
9
+ if ( typeof define == 'function' && define.amd )
10
+ define( ['picker', 'jquery'], factory )
11
+
12
+ // Node.js/browserify.
13
+ else if ( typeof exports == 'object' )
14
+ module.exports = factory( require('./picker.js'), require('jquery') )
15
+
16
+ // Browser globals.
17
+ else factory( Picker, jQuery )
18
+
19
+ }(function( Picker, $ ) {
20
+
21
+
22
+ /**
23
+ * Globals and constants
24
+ */
25
+ var HOURS_IN_DAY = 24,
26
+ MINUTES_IN_HOUR = 60,
27
+ HOURS_TO_NOON = 12,
28
+ MINUTES_IN_DAY = HOURS_IN_DAY * MINUTES_IN_HOUR,
29
+ _ = Picker._
30
+
31
+
32
+
33
+ /**
34
+ * The time picker constructor
35
+ */
36
+ function TimePicker( picker, settings ) {
37
+
38
+ var clock = this,
39
+ elementValue = picker.$node[ 0 ].value,
40
+ elementDataValue = picker.$node.data( 'value' ),
41
+ valueString = elementDataValue || elementValue,
42
+ formatString = elementDataValue ? settings.formatSubmit : settings.format
43
+
44
+ clock.settings = settings
45
+ clock.$node = picker.$node
46
+
47
+ // The queue of methods that will be used to build item objects.
48
+ clock.queue = {
49
+ interval: 'i',
50
+ min: 'measure create',
51
+ max: 'measure create',
52
+ now: 'now create',
53
+ select: 'parse create validate',
54
+ highlight: 'parse create validate',
55
+ view: 'parse create validate',
56
+ disable: 'deactivate',
57
+ enable: 'activate'
58
+ }
59
+
60
+ // The component's item object.
61
+ clock.item = {}
62
+
63
+ clock.item.clear = null
64
+ clock.item.interval = settings.interval || 30
65
+ clock.item.disable = ( settings.disable || [] ).slice( 0 )
66
+ clock.item.enable = -(function( collectionDisabled ) {
67
+ return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1
68
+ })( clock.item.disable )
69
+
70
+ clock.
71
+ set( 'min', settings.min ).
72
+ set( 'max', settings.max ).
73
+ set( 'now' )
74
+
75
+ // When there’s a value, set the `select`, which in turn
76
+ // also sets the `highlight` and `view`.
77
+ if ( valueString ) {
78
+ clock.set( 'select', valueString, {
79
+ format: formatString
80
+ })
81
+ }
82
+
83
+ // If there’s no value, default to highlighting “today”.
84
+ else {
85
+ clock.
86
+ set( 'select', null ).
87
+ set( 'highlight', clock.item.now )
88
+ }
89
+
90
+ // The keycode to movement mapping.
91
+ clock.key = {
92
+ 40: 1, // Down
93
+ 38: -1, // Up
94
+ 39: 1, // Right
95
+ 37: -1, // Left
96
+ go: function( timeChange ) {
97
+ clock.set(
98
+ 'highlight',
99
+ clock.item.highlight.pick + timeChange * clock.item.interval,
100
+ { interval: timeChange * clock.item.interval }
101
+ )
102
+ this.render()
103
+ }
104
+ }
105
+
106
+
107
+ // Bind some picker events.
108
+ picker.
109
+ on( 'render', function() {
110
+ var $pickerHolder = picker.$root.children(),
111
+ $viewset = $pickerHolder.find( '.' + settings.klass.viewset ),
112
+ vendors = function( prop ) {
113
+ return ['webkit', 'moz', 'ms', 'o', ''].map(function( vendor ) {
114
+ return ( vendor ? '-' + vendor + '-' : '' ) + prop
115
+ })
116
+ },
117
+ animations = function( $el, state ) {
118
+ vendors( 'transform' ).map(function( prop ) {
119
+ $el.css( prop, state )
120
+ })
121
+ vendors( 'transition' ).map(function( prop ) {
122
+ $el.css( prop, state )
123
+ })
124
+ }
125
+ if ( $viewset.length ) {
126
+ animations( $pickerHolder, 'none' )
127
+ $pickerHolder[ 0 ].scrollTop = ~~$viewset.position().top - ( $viewset[ 0 ].clientHeight * 2 )
128
+ animations( $pickerHolder, '' )
129
+ }
130
+ }, 1 ).
131
+ on( 'open', function() {
132
+ picker.$root.find( 'button' ).attr( 'disabled', false )
133
+ }, 1 ).
134
+ on( 'close', function() {
135
+ picker.$root.find( 'button' ).attr( 'disabled', true )
136
+ }, 1 )
137
+
138
+ } //TimePicker
139
+
140
+
141
+ /**
142
+ * Set a timepicker item object.
143
+ */
144
+ TimePicker.prototype.set = function( type, value, options ) {
145
+
146
+ var clock = this,
147
+ clockItem = clock.item
148
+
149
+ // If the value is `null` just set it immediately.
150
+ if ( value === null ) {
151
+ if ( type == 'clear' ) type = 'select'
152
+ clockItem[ type ] = value
153
+ return clock
154
+ }
155
+
156
+ // Otherwise go through the queue of methods, and invoke the functions.
157
+ // Update this as the time unit, and set the final value as this item.
158
+ // * In the case of `enable`, keep the queue but set `disable` instead.
159
+ // And in the case of `flip`, keep the queue but set `enable` instead.
160
+ clockItem[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = clock.queue[ type ].split( ' ' ).map( function( method ) {
161
+ value = clock[ method ]( type, value, options )
162
+ return value
163
+ }).pop()
164
+
165
+ // Check if we need to cascade through more updates.
166
+ if ( type == 'select' ) {
167
+ clock.set( 'highlight', clockItem.select, options )
168
+ }
169
+ else if ( type == 'highlight' ) {
170
+ clock.set( 'view', clockItem.highlight, options )
171
+ }
172
+ else if ( type == 'interval' ) {
173
+ clock.
174
+ set( 'min', clockItem.min, options ).
175
+ set( 'max', clockItem.max, options )
176
+ }
177
+ else if ( type.match( /^(flip|min|max|disable|enable)$/ ) ) {
178
+ if ( clockItem.select && clock.disabled( clockItem.select ) ) {
179
+ clock.set( 'select', value, options )
180
+ }
181
+ if ( clockItem.highlight && clock.disabled( clockItem.highlight ) ) {
182
+ clock.set( 'highlight', value, options )
183
+ }
184
+ if ( type == 'min' ) {
185
+ clock.set( 'max', clockItem.max, options )
186
+ }
187
+ }
188
+
189
+ return clock
190
+ } //TimePicker.prototype.set
191
+
192
+
193
+ /**
194
+ * Get a timepicker item object.
195
+ */
196
+ TimePicker.prototype.get = function( type ) {
197
+ return this.item[ type ]
198
+ } //TimePicker.prototype.get
199
+
200
+
201
+ /**
202
+ * Create a picker time object.
203
+ */
204
+ TimePicker.prototype.create = function( type, value, options ) {
205
+
206
+ var clock = this
207
+
208
+ // If there’s no value, use the type as the value.
209
+ value = value === undefined ? type : value
210
+
211
+ // If it’s a date object, convert it into an array.
212
+ if ( _.isDate( value ) ) {
213
+ value = [ value.getHours(), value.getMinutes() ]
214
+ }
215
+
216
+ // If it’s an object, use the “pick” value.
217
+ if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
218
+ value = value.pick
219
+ }
220
+
221
+ // If it’s an array, convert it into minutes.
222
+ else if ( $.isArray( value ) ) {
223
+ value = +value[ 0 ] * MINUTES_IN_HOUR + (+value[ 1 ])
224
+ }
225
+
226
+ // If no valid value is passed, set it to “now”.
227
+ else if ( !_.isInteger( value ) ) {
228
+ value = clock.now( type, value, options )
229
+ }
230
+
231
+ // If we’re setting the max, make sure it’s greater than the min.
232
+ if ( type == 'max' && value < clock.item.min.pick ) {
233
+ value += MINUTES_IN_DAY
234
+ }
235
+
236
+ // If the value doesn’t fall directly on the interval,
237
+ // add one interval to indicate it as “passed”.
238
+ if ( type != 'min' && type != 'max' && (value - clock.item.min.pick) % clock.item.interval !== 0 ) {
239
+ value += clock.item.interval
240
+ }
241
+
242
+ // Normalize it into a “reachable” interval.
243
+ value = clock.normalize( type, value, options )
244
+
245
+ // Return the compiled object.
246
+ return {
247
+
248
+ // Divide to get hours from minutes.
249
+ hour: ~~( HOURS_IN_DAY + value / MINUTES_IN_HOUR ) % HOURS_IN_DAY,
250
+
251
+ // The remainder is the minutes.
252
+ mins: ( MINUTES_IN_HOUR + value % MINUTES_IN_HOUR ) % MINUTES_IN_HOUR,
253
+
254
+ // The time in total minutes.
255
+ time: ( MINUTES_IN_DAY + value ) % MINUTES_IN_DAY,
256
+
257
+ // Reference to the “relative” value to pick.
258
+ pick: value % MINUTES_IN_DAY
259
+ }
260
+ } //TimePicker.prototype.create
261
+
262
+
263
+ /**
264
+ * Create a range limit object using an array, date object,
265
+ * literal “true”, or integer relative to another time.
266
+ */
267
+ TimePicker.prototype.createRange = function( from, to ) {
268
+
269
+ var clock = this,
270
+ createTime = function( time ) {
271
+ if ( time === true || $.isArray( time ) || _.isDate( time ) ) {
272
+ return clock.create( time )
273
+ }
274
+ return time
275
+ }
276
+
277
+ // Create objects if possible.
278
+ if ( !_.isInteger( from ) ) {
279
+ from = createTime( from )
280
+ }
281
+ if ( !_.isInteger( to ) ) {
282
+ to = createTime( to )
283
+ }
284
+
285
+ // Create relative times.
286
+ if ( _.isInteger( from ) && $.isPlainObject( to ) ) {
287
+ from = [ to.hour, to.mins + ( from * clock.settings.interval ) ];
288
+ }
289
+ else if ( _.isInteger( to ) && $.isPlainObject( from ) ) {
290
+ to = [ from.hour, from.mins + ( to * clock.settings.interval ) ];
291
+ }
292
+
293
+ return {
294
+ from: createTime( from ),
295
+ to: createTime( to )
296
+ }
297
+ } //TimePicker.prototype.createRange
298
+
299
+
300
+ /**
301
+ * Check if a time unit falls within a time range object.
302
+ */
303
+ TimePicker.prototype.withinRange = function( range, timeUnit ) {
304
+ range = this.createRange(range.from, range.to)
305
+ return timeUnit.pick >= range.from.pick && timeUnit.pick <= range.to.pick
306
+ }
307
+
308
+
309
+ /**
310
+ * Check if two time range objects overlap.
311
+ */
312
+ TimePicker.prototype.overlapRanges = function( one, two ) {
313
+
314
+ var clock = this
315
+
316
+ // Convert the ranges into comparable times.
317
+ one = clock.createRange( one.from, one.to )
318
+ two = clock.createRange( two.from, two.to )
319
+
320
+ return clock.withinRange( one, two.from ) || clock.withinRange( one, two.to ) ||
321
+ clock.withinRange( two, one.from ) || clock.withinRange( two, one.to )
322
+ }
323
+
324
+
325
+ /**
326
+ * Get the time relative to now.
327
+ */
328
+ TimePicker.prototype.now = function( type, value/*, options*/ ) {
329
+
330
+ var interval = this.item.interval,
331
+ date = new Date(),
332
+ nowMinutes = date.getHours() * MINUTES_IN_HOUR + date.getMinutes(),
333
+ isValueInteger = _.isInteger( value ),
334
+ isBelowInterval
335
+
336
+ // Make sure “now” falls within the interval range.
337
+ nowMinutes -= nowMinutes % interval
338
+
339
+ // Check if the difference is less than the interval itself.
340
+ isBelowInterval = value < 0 && interval * value + nowMinutes <= -interval
341
+
342
+ // Add an interval because the time has “passed”.
343
+ nowMinutes += type == 'min' && isBelowInterval ? 0 : interval
344
+
345
+ // If the value is a number, adjust by that many intervals.
346
+ if ( isValueInteger ) {
347
+ nowMinutes += interval * (
348
+ isBelowInterval && type != 'max' ?
349
+ value + 1 :
350
+ value
351
+ )
352
+ }
353
+
354
+ // Return the final calculation.
355
+ return nowMinutes
356
+ } //TimePicker.prototype.now
357
+
358
+
359
+ /**
360
+ * Normalize minutes to be “reachable” based on the min and interval.
361
+ */
362
+ TimePicker.prototype.normalize = function( type, value/*, options*/ ) {
363
+
364
+ var interval = this.item.interval,
365
+ minTime = this.item.min && this.item.min.pick || 0
366
+
367
+ // If setting min time, don’t shift anything.
368
+ // Otherwise get the value and min difference and then
369
+ // normalize the difference with the interval.
370
+ value -= type == 'min' ? 0 : ( value - minTime ) % interval
371
+
372
+ // Return the adjusted value.
373
+ return value
374
+ } //TimePicker.prototype.normalize
375
+
376
+
377
+ /**
378
+ * Measure the range of minutes.
379
+ */
380
+ TimePicker.prototype.measure = function( type, value, options ) {
381
+
382
+ var clock = this
383
+
384
+ // If it’s anything false-y, set it to the default.
385
+ if ( !value ) {
386
+ value = type == 'min' ? [ 0, 0 ] : [ HOURS_IN_DAY - 1, MINUTES_IN_HOUR - 1 ]
387
+ }
388
+
389
+ // If it’s a string, parse it.
390
+ if ( typeof value == 'string' ) {
391
+ value = clock.parse( type, value )
392
+ }
393
+
394
+ // If it’s a literal true, or an integer, make it relative to now.
395
+ else if ( value === true || _.isInteger( value ) ) {
396
+ value = clock.now( type, value, options )
397
+ }
398
+
399
+ // If it’s an object already, just normalize it.
400
+ else if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
401
+ value = clock.normalize( type, value.pick, options )
402
+ }
403
+
404
+ return value
405
+ } ///TimePicker.prototype.measure
406
+
407
+
408
+ /**
409
+ * Validate an object as enabled.
410
+ */
411
+ TimePicker.prototype.validate = function( type, timeObject, options ) {
412
+
413
+ var clock = this,
414
+ interval = options && options.interval ? options.interval : clock.item.interval
415
+
416
+ // Check if the object is disabled.
417
+ if ( clock.disabled( timeObject ) ) {
418
+
419
+ // Shift with the interval until we reach an enabled time.
420
+ timeObject = clock.shift( timeObject, interval )
421
+ }
422
+
423
+ // Scope the object into range.
424
+ timeObject = clock.scope( timeObject )
425
+
426
+ // Do a second check to see if we landed on a disabled min/max.
427
+ // In that case, shift using the opposite interval as before.
428
+ if ( clock.disabled( timeObject ) ) {
429
+ timeObject = clock.shift( timeObject, interval * -1 )
430
+ }
431
+
432
+ // Return the final object.
433
+ return timeObject
434
+ } //TimePicker.prototype.validate
435
+
436
+
437
+ /**
438
+ * Check if an object is disabled.
439
+ */
440
+ TimePicker.prototype.disabled = function( timeToVerify ) {
441
+
442
+ var clock = this,
443
+
444
+ // Filter through the disabled times to check if this is one.
445
+ isDisabledMatch = clock.item.disable.filter( function( timeToDisable ) {
446
+
447
+ // If the time is a number, match the hours.
448
+ if ( _.isInteger( timeToDisable ) ) {
449
+ return timeToVerify.hour == timeToDisable
450
+ }
451
+
452
+ // If it’s an array, create the object and match the times.
453
+ if ( $.isArray( timeToDisable ) || _.isDate( timeToDisable ) ) {
454
+ return timeToVerify.pick == clock.create( timeToDisable ).pick
455
+ }
456
+
457
+ // If it’s an object, match a time within the “from” and “to” range.
458
+ if ( $.isPlainObject( timeToDisable ) ) {
459
+ return clock.withinRange( timeToDisable, timeToVerify )
460
+ }
461
+ })
462
+
463
+ // If this time matches a disabled time, confirm it’s not inverted.
464
+ isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function( timeToDisable ) {
465
+ return $.isArray( timeToDisable ) && timeToDisable[2] == 'inverted' ||
466
+ $.isPlainObject( timeToDisable ) && timeToDisable.inverted
467
+ }).length
468
+
469
+ // If the clock is "enabled" flag is flipped, flip the condition.
470
+ return clock.item.enable === -1 ? !isDisabledMatch : isDisabledMatch ||
471
+ timeToVerify.pick < clock.item.min.pick ||
472
+ timeToVerify.pick > clock.item.max.pick
473
+ } //TimePicker.prototype.disabled
474
+
475
+
476
+ /**
477
+ * Shift an object by an interval until we reach an enabled object.
478
+ */
479
+ TimePicker.prototype.shift = function( timeObject, interval ) {
480
+
481
+ var clock = this,
482
+ minLimit = clock.item.min.pick,
483
+ maxLimit = clock.item.max.pick/*,
484
+ safety = 1000*/
485
+
486
+ interval = interval || clock.item.interval
487
+
488
+ // Keep looping as long as the time is disabled.
489
+ while ( /*safety &&*/ clock.disabled( timeObject ) ) {
490
+
491
+ /*safety -= 1
492
+ if ( !safety ) {
493
+ throw 'Fell into an infinite loop while shifting to ' + timeObject.hour + ':' + timeObject.mins + '.'
494
+ }*/
495
+
496
+ // Increase/decrease the time by the interval and keep looping.
497
+ timeObject = clock.create( timeObject.pick += interval )
498
+
499
+ // If we've looped beyond the limits, break out of the loop.
500
+ if ( timeObject.pick <= minLimit || timeObject.pick >= maxLimit ) {
501
+ break
502
+ }
503
+ }
504
+
505
+ // Return the final object.
506
+ return timeObject
507
+ } //TimePicker.prototype.shift
508
+
509
+
510
+ /**
511
+ * Scope an object to be within range of min and max.
512
+ */
513
+ TimePicker.prototype.scope = function( timeObject ) {
514
+ var minLimit = this.item.min.pick,
515
+ maxLimit = this.item.max.pick
516
+ return this.create( timeObject.pick > maxLimit ? maxLimit : timeObject.pick < minLimit ? minLimit : timeObject )
517
+ } //TimePicker.prototype.scope
518
+
519
+
520
+ /**
521
+ * Parse a string into a usable type.
522
+ */
523
+ TimePicker.prototype.parse = function( type, value, options ) {
524
+
525
+ var hour, minutes, isPM, item, parseValue,
526
+ clock = this,
527
+ parsingObject = {}
528
+
529
+ // If it’s already parsed, we’re good.
530
+ if ( !value || typeof value != 'string' ) {
531
+ return value
532
+ }
533
+
534
+ // We need a `.format` to parse the value with.
535
+ if ( !( options && options.format ) ) {
536
+ options = options || {}
537
+ options.format = clock.settings.format
538
+ }
539
+
540
+ // Convert the format into an array and then map through it.
541
+ clock.formats.toArray( options.format ).map( function( label ) {
542
+
543
+ var
544
+ substring,
545
+
546
+ // Grab the formatting label.
547
+ formattingLabel = clock.formats[ label ],
548
+
549
+ // The format length is from the formatting label function or the
550
+ // label length without the escaping exclamation (!) mark.
551
+ formatLength = formattingLabel ?
552
+ _.trigger( formattingLabel, clock, [ value, parsingObject ] ) :
553
+ label.replace( /^!/, '' ).length
554
+
555
+ // If there's a format label, split the value up to the format length.
556
+ // Then add it to the parsing object with appropriate label.
557
+ if ( formattingLabel ) {
558
+ substring = value.substr( 0, formatLength )
559
+ parsingObject[ label ] = substring.match(/^\d+$/) ? +substring : substring
560
+ }
561
+
562
+ // Update the time value as the substring from format length to end.
563
+ value = value.substr( formatLength )
564
+ })
565
+
566
+ // Grab the hour and minutes from the parsing object.
567
+ for ( item in parsingObject ) {
568
+ parseValue = parsingObject[item]
569
+ if ( _.isInteger(parseValue) ) {
570
+ if ( item.match(/^(h|hh)$/i) ) {
571
+ hour = parseValue
572
+ if ( item == 'h' || item == 'hh' ) {
573
+ hour %= 12
574
+ }
575
+ }
576
+ else if ( item == 'i' ) {
577
+ minutes = parseValue
578
+ }
579
+ }
580
+ else if ( item.match(/^a$/i) && parseValue.match(/^p/i) && ('h' in parsingObject || 'hh' in parsingObject) ) {
581
+ isPM = true
582
+ }
583
+ }
584
+
585
+ // Calculate it in minutes and return.
586
+ return (isPM ? hour + 12 : hour) * MINUTES_IN_HOUR + minutes
587
+ } //TimePicker.prototype.parse
588
+
589
+
590
+ /**
591
+ * Various formats to display the object in.
592
+ */
593
+ TimePicker.prototype.formats = {
594
+
595
+ h: function( string, timeObject ) {
596
+
597
+ // If there's string, then get the digits length.
598
+ // Otherwise return the selected hour in "standard" format.
599
+ return string ? _.digits( string ) : timeObject.hour % HOURS_TO_NOON || HOURS_TO_NOON
600
+ },
601
+ hh: function( string, timeObject ) {
602
+
603
+ // If there's a string, then the length is always 2.
604
+ // Otherwise return the selected hour in "standard" format with a leading zero.
605
+ return string ? 2 : _.lead( timeObject.hour % HOURS_TO_NOON || HOURS_TO_NOON )
606
+ },
607
+ H: function( string, timeObject ) {
608
+
609
+ // If there's string, then get the digits length.
610
+ // Otherwise return the selected hour in "military" format as a string.
611
+ return string ? _.digits( string ) : '' + ( timeObject.hour % 24 )
612
+ },
613
+ HH: function( string, timeObject ) {
614
+
615
+ // If there's string, then get the digits length.
616
+ // Otherwise return the selected hour in "military" format with a leading zero.
617
+ return string ? _.digits( string ) : _.lead( timeObject.hour % 24 )
618
+ },
619
+ i: function( string, timeObject ) {
620
+
621
+ // If there's a string, then the length is always 2.
622
+ // Otherwise return the selected minutes.
623
+ return string ? 2 : _.lead( timeObject.mins )
624
+ },
625
+ a: function( string, timeObject ) {
626
+
627
+ // If there's a string, then the length is always 4.
628
+ // Otherwise check if it's more than "noon" and return either am/pm.
629
+ return string ? 4 : MINUTES_IN_DAY / 2 > timeObject.time % MINUTES_IN_DAY ? 'a.m.' : 'p.m.'
630
+ },
631
+ A: function( string, timeObject ) {
632
+
633
+ // If there's a string, then the length is always 2.
634
+ // Otherwise check if it's more than "noon" and return either am/pm.
635
+ return string ? 2 : MINUTES_IN_DAY / 2 > timeObject.time % MINUTES_IN_DAY ? 'AM' : 'PM'
636
+ },
637
+
638
+ // Create an array by splitting the formatting string passed.
639
+ toArray: function( formatString ) { return formatString.split( /(h{1,2}|H{1,2}|i|a|A|!.)/g ) },
640
+
641
+ // Format an object into a string using the formatting options.
642
+ toString: function ( formatString, itemObject ) {
643
+ var clock = this
644
+ return clock.formats.toArray( formatString ).map( function( label ) {
645
+ return _.trigger( clock.formats[ label ], clock, [ 0, itemObject ] ) || label.replace( /^!/, '' )
646
+ }).join( '' )
647
+ }
648
+ } //TimePicker.prototype.formats
649
+
650
+
651
+
652
+
653
+ /**
654
+ * Check if two time units are the exact.
655
+ */
656
+ TimePicker.prototype.isTimeExact = function( one, two ) {
657
+
658
+ var clock = this
659
+
660
+ // When we’re working with minutes, do a direct comparison.
661
+ if (
662
+ ( _.isInteger( one ) && _.isInteger( two ) ) ||
663
+ ( typeof one == 'boolean' && typeof two == 'boolean' )
664
+ ) {
665
+ return one === two
666
+ }
667
+
668
+ // When we’re working with time representations, compare the “pick” value.
669
+ if (
670
+ ( _.isDate( one ) || $.isArray( one ) ) &&
671
+ ( _.isDate( two ) || $.isArray( two ) )
672
+ ) {
673
+ return clock.create( one ).pick === clock.create( two ).pick
674
+ }
675
+
676
+ // When we’re working with range objects, compare the “from” and “to”.
677
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
678
+ return clock.isTimeExact( one.from, two.from ) && clock.isTimeExact( one.to, two.to )
679
+ }
680
+
681
+ return false
682
+ }
683
+
684
+
685
+ /**
686
+ * Check if two time units overlap.
687
+ */
688
+ TimePicker.prototype.isTimeOverlap = function( one, two ) {
689
+
690
+ var clock = this
691
+
692
+ // When we’re working with an integer, compare the hours.
693
+ if ( _.isInteger( one ) && ( _.isDate( two ) || $.isArray( two ) ) ) {
694
+ return one === clock.create( two ).hour
695
+ }
696
+ if ( _.isInteger( two ) && ( _.isDate( one ) || $.isArray( one ) ) ) {
697
+ return two === clock.create( one ).hour
698
+ }
699
+
700
+ // When we’re working with range objects, check if the ranges overlap.
701
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
702
+ return clock.overlapRanges( one, two )
703
+ }
704
+
705
+ return false
706
+ }
707
+
708
+
709
+ /**
710
+ * Flip the “enabled” state.
711
+ */
712
+ TimePicker.prototype.flipEnable = function(val) {
713
+ var itemObject = this.item
714
+ itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1)
715
+ }
716
+
717
+
718
+ /**
719
+ * Mark a collection of times as “disabled”.
720
+ */
721
+ TimePicker.prototype.deactivate = function( type, timesToDisable ) {
722
+
723
+ var clock = this,
724
+ disabledItems = clock.item.disable.slice(0)
725
+
726
+
727
+ // If we’re flipping, that’s all we need to do.
728
+ if ( timesToDisable == 'flip' ) {
729
+ clock.flipEnable()
730
+ }
731
+
732
+ else if ( timesToDisable === false ) {
733
+ clock.flipEnable(1)
734
+ disabledItems = []
735
+ }
736
+
737
+ else if ( timesToDisable === true ) {
738
+ clock.flipEnable(-1)
739
+ disabledItems = []
740
+ }
741
+
742
+ // Otherwise go through the times to disable.
743
+ else {
744
+
745
+ timesToDisable.map(function( unitToDisable ) {
746
+
747
+ var matchFound
748
+
749
+ // When we have disabled items, check for matches.
750
+ // If something is matched, immediately break out.
751
+ for ( var index = 0; index < disabledItems.length; index += 1 ) {
752
+ if ( clock.isTimeExact( unitToDisable, disabledItems[index] ) ) {
753
+ matchFound = true
754
+ break
755
+ }
756
+ }
757
+
758
+ // If nothing was found, add the validated unit to the collection.
759
+ if ( !matchFound ) {
760
+ if (
761
+ _.isInteger( unitToDisable ) ||
762
+ _.isDate( unitToDisable ) ||
763
+ $.isArray( unitToDisable ) ||
764
+ ( $.isPlainObject( unitToDisable ) && unitToDisable.from && unitToDisable.to )
765
+ ) {
766
+ disabledItems.push( unitToDisable )
767
+ }
768
+ }
769
+ })
770
+ }
771
+
772
+ // Return the updated collection.
773
+ return disabledItems
774
+ } //TimePicker.prototype.deactivate
775
+
776
+
777
+ /**
778
+ * Mark a collection of times as “enabled”.
779
+ */
780
+ TimePicker.prototype.activate = function( type, timesToEnable ) {
781
+
782
+ var clock = this,
783
+ disabledItems = clock.item.disable,
784
+ disabledItemsCount = disabledItems.length
785
+
786
+ // If we’re flipping, that’s all we need to do.
787
+ if ( timesToEnable == 'flip' ) {
788
+ clock.flipEnable()
789
+ }
790
+
791
+ else if ( timesToEnable === true ) {
792
+ clock.flipEnable(1)
793
+ disabledItems = []
794
+ }
795
+
796
+ else if ( timesToEnable === false ) {
797
+ clock.flipEnable(-1)
798
+ disabledItems = []
799
+ }
800
+
801
+ // Otherwise go through the disabled times.
802
+ else {
803
+
804
+ timesToEnable.map(function( unitToEnable ) {
805
+
806
+ var matchFound,
807
+ disabledUnit,
808
+ index,
809
+ isRangeMatched
810
+
811
+ // Go through the disabled items and try to find a match.
812
+ for ( index = 0; index < disabledItemsCount; index += 1 ) {
813
+
814
+ disabledUnit = disabledItems[index]
815
+
816
+ // When an exact match is found, remove it from the collection.
817
+ if ( clock.isTimeExact( disabledUnit, unitToEnable ) ) {
818
+ matchFound = disabledItems[index] = null
819
+ isRangeMatched = true
820
+ break
821
+ }
822
+
823
+ // When an overlapped match is found, add the “inverted” state to it.
824
+ else if ( clock.isTimeOverlap( disabledUnit, unitToEnable ) ) {
825
+ if ( $.isPlainObject( unitToEnable ) ) {
826
+ unitToEnable.inverted = true
827
+ matchFound = unitToEnable
828
+ }
829
+ else if ( $.isArray( unitToEnable ) ) {
830
+ matchFound = unitToEnable
831
+ if ( !matchFound[2] ) matchFound.push( 'inverted' )
832
+ }
833
+ else if ( _.isDate( unitToEnable ) ) {
834
+ matchFound = [ unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted' ]
835
+ }
836
+ break
837
+ }
838
+ }
839
+
840
+ // If a match was found, remove a previous duplicate entry.
841
+ if ( matchFound ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
842
+ if ( clock.isTimeExact( disabledItems[index], unitToEnable ) ) {
843
+ disabledItems[index] = null
844
+ break
845
+ }
846
+ }
847
+
848
+ // In the event that we’re dealing with an overlap of range times,
849
+ // make sure there are no “inverted” times because of it.
850
+ if ( isRangeMatched ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
851
+ if ( clock.isTimeOverlap( disabledItems[index], unitToEnable ) ) {
852
+ disabledItems[index] = null
853
+ break
854
+ }
855
+ }
856
+
857
+ // If something is still matched, add it into the collection.
858
+ if ( matchFound ) {
859
+ disabledItems.push( matchFound )
860
+ }
861
+ })
862
+ }
863
+
864
+ // Return the updated collection.
865
+ return disabledItems.filter(function( val ) { return val != null })
866
+ } //TimePicker.prototype.activate
867
+
868
+
869
+ /**
870
+ * The division to use for the range intervals.
871
+ */
872
+ TimePicker.prototype.i = function( type, value/*, options*/ ) {
873
+ return _.isInteger( value ) && value > 0 ? value : this.item.interval
874
+ }
875
+
876
+
877
+ /**
878
+ * Create a string for the nodes in the picker.
879
+ */
880
+ TimePicker.prototype.nodes = function( isOpen ) {
881
+
882
+ var
883
+ clock = this,
884
+ settings = clock.settings,
885
+ selectedObject = clock.item.select,
886
+ highlightedObject = clock.item.highlight,
887
+ viewsetObject = clock.item.view,
888
+ disabledCollection = clock.item.disable
889
+
890
+ return _.node(
891
+ 'ul',
892
+ _.group({
893
+ min: clock.item.min.pick,
894
+ max: clock.item.max.pick,
895
+ i: clock.item.interval,
896
+ node: 'li',
897
+ item: function( loopedTime ) {
898
+ loopedTime = clock.create( loopedTime )
899
+ var timeMinutes = loopedTime.pick,
900
+ isSelected = selectedObject && selectedObject.pick == timeMinutes,
901
+ isHighlighted = highlightedObject && highlightedObject.pick == timeMinutes,
902
+ isDisabled = disabledCollection && clock.disabled( loopedTime ),
903
+ formattedTime = _.trigger( clock.formats.toString, clock, [ settings.format, loopedTime ] )
904
+ return [
905
+ _.trigger( clock.formats.toString, clock, [ _.trigger( settings.formatLabel, clock, [ loopedTime ] ) || settings.format, loopedTime ] ),
906
+ (function( klasses ) {
907
+
908
+ if ( isSelected ) {
909
+ klasses.push( settings.klass.selected )
910
+ }
911
+
912
+ if ( isHighlighted ) {
913
+ klasses.push( settings.klass.highlighted )
914
+ }
915
+
916
+ if ( viewsetObject && viewsetObject.pick == timeMinutes ) {
917
+ klasses.push( settings.klass.viewset )
918
+ }
919
+
920
+ if ( isDisabled ) {
921
+ klasses.push( settings.klass.disabled )
922
+ }
923
+
924
+ return klasses.join( ' ' )
925
+ })( [ settings.klass.listItem ] ),
926
+ 'data-pick=' + loopedTime.pick + ' ' + _.ariaAttr({
927
+ role: 'option',
928
+ label: formattedTime,
929
+ selected: isSelected && clock.$node.val() === formattedTime ? true : null,
930
+ activedescendant: isHighlighted ? true : null,
931
+ disabled: isDisabled ? true : null
932
+ })
933
+ ]
934
+ }
935
+ }) +
936
+
937
+ // * For Firefox forms to submit, make sure to set the button’s `type` attribute as “button”.
938
+ _.node(
939
+ 'li',
940
+ _.node(
941
+ 'button',
942
+ settings.clear,
943
+ settings.klass.buttonClear,
944
+ 'type=button data-clear=1' + ( isOpen ? '' : ' disabled' ) + ' ' +
945
+ _.ariaAttr({ controls: clock.$node[0].id })
946
+ ),
947
+ '', _.ariaAttr({ role: 'presentation' })
948
+ ),
949
+ settings.klass.list,
950
+ _.ariaAttr({ role: 'listbox', controls: clock.$node[0].id })
951
+ )
952
+ } //TimePicker.prototype.nodes
953
+
954
+
955
+
956
+
957
+
958
+
959
+
960
+ /* ==========================================================================
961
+ Extend the picker to add the component with the defaults.
962
+ ========================================================================== */
963
+
964
+ TimePicker.defaults = (function( prefix ) {
965
+
966
+ return {
967
+
968
+ // Clear
969
+ clear: 'Clear',
970
+
971
+ // The format to show on the `input` element
972
+ format: 'h:i A',
973
+
974
+ // The interval between each time
975
+ interval: 30,
976
+
977
+ // Classes
978
+ klass: {
979
+
980
+ picker: prefix + ' ' + prefix + '--time',
981
+ holder: prefix + '__holder',
982
+
983
+ list: prefix + '__list',
984
+ listItem: prefix + '__list-item',
985
+
986
+ disabled: prefix + '__list-item--disabled',
987
+ selected: prefix + '__list-item--selected',
988
+ highlighted: prefix + '__list-item--highlighted',
989
+ viewset: prefix + '__list-item--viewset',
990
+ now: prefix + '__list-item--now',
991
+
992
+ buttonClear: prefix + '__button--clear'
993
+ }
994
+ }
995
+ })( Picker.klasses().picker )
996
+
997
+
998
+
999
+
1000
+
1001
+ /**
1002
+ * Extend the picker to add the time picker.
1003
+ */
1004
+ Picker.extend( 'pickatime', TimePicker )
1005
+
1006
+
1007
+ }));
1008
+
1009
+
1010
+
lib/simple-admin-pages/lib/pickadate/themes/default.css CHANGED
@@ -1,4 +1,172 @@
1
- .picker{font-size:16px;text-align:left;line-height:1.2;color:#000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  * Default mobile-first, responsive styling for pickadate.js
3
  * Demo: http://amsul.github.io/pickadate.js
4
- */.picker__frame,.picker__holder{bottom:0;left:0;right:0;top:100%}.picker__holder{position:fixed;-webkit-transition:background .15s ease-out,top 0s .15s;-moz-transition:background .15s ease-out,top 0s .15s;transition:background .15s ease-out,top 0s .15s}.picker__frame{position:absolute;margin:0 auto;min-width:256px;max-width:666px;width:100%;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;-webkit-transition:all .15s ease-out;-moz-transition:all .15s ease-out;transition:all .15s ease-out}@media (min-height:33.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}}@media (min-height:40.125em){.picker__frame{margin-bottom:7.5%}}.picker__wrap{display:table;width:100%;height:100%}@media (min-height:33.875em){.picker__wrap{display:block}}.picker__box{background:#fff;display:table-cell;vertical-align:middle}@media (min-height:26.5em){.picker__box{font-size:1.25em}}@media (min-height:33.875em){.picker__box{display:block;font-size:1.33em;border:1px solid #777;border-top-color:#898989;border-bottom-width:0;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;-webkit-box-shadow:0 12px 36px 16px rgba(0,0,0,.24);-moz-box-shadow:0 12px 36px 16px rgba(0,0,0,.24);box-shadow:0 12px 36px 16px rgba(0,0,0,.24)}}@media (min-height:40.125em){.picker__box{font-size:1.5em;border-bottom-width:1px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}}.picker--opened .picker__holder{top:0;zoom:1;background:rgba(0,0,0,.32);-webkit-transition:background .15s ease-out;-moz-transition:background .15s ease-out;transition:background .15s ease-out}.picker--opened .picker__frame{top:0;-ms-filter:"alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}@media (min-height:33.875em){.picker--opened .picker__frame{top:auto;bottom:0}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ==========================================================================
2
+ $BASE-PICKER
3
+ ========================================================================== */
4
+ /**
5
+ * Note: the root picker element should *NOT* be styled more than what’s here.
6
+ */
7
+ .picker {
8
+ font-size: 16px;
9
+ text-align: left;
10
+ line-height: 1.2;
11
+ color: #000000;
12
+ position: absolute;
13
+ z-index: 10000;
14
+ -webkit-user-select: none;
15
+ -moz-user-select: none;
16
+ -ms-user-select: none;
17
+ user-select: none;
18
+ }
19
+ /**
20
+ * The picker input element.
21
+ */
22
+ .picker__input {
23
+ cursor: default;
24
+ }
25
+ /**
26
+ * When the picker is opened, the input element is “activated”.
27
+ */
28
+ .picker__input.picker__input--active {
29
+ border-color: #0089ec;
30
+ }
31
+ /**
32
+ * The holder is the only “scrollable” top-level container element.
33
+ */
34
+ .picker__holder {
35
+ width: 100%;
36
+ overflow-y: auto;
37
+ -webkit-overflow-scrolling: touch;
38
+ }
39
+
40
+ /*!
41
  * Default mobile-first, responsive styling for pickadate.js
42
  * Demo: http://amsul.github.io/pickadate.js
43
+ */
44
+ /**
45
+ * Note: the root picker element should *NOT* be styled more than what’s here.
46
+ */
47
+ /**
48
+ * Make the holder and frame fullscreen.
49
+ */
50
+ .picker__holder,
51
+ .picker__frame {
52
+ top: 0;
53
+ bottom: 0;
54
+ left: 0;
55
+ right: 0;
56
+ -webkit-transform: translateY(100%);
57
+ -ms-transform: translateY(100%);
58
+ transform: translateY(100%);
59
+ }
60
+ /**
61
+ * The holder should overlay the entire screen.
62
+ */
63
+ .picker__holder {
64
+ position: fixed;
65
+ -webkit-transition: background 0.15s ease-out;
66
+ -webkit-transform: 0s 0.15s;
67
+ transition: background 0.15s ease-out;
68
+ transform: 0s 0.15s;
69
+ -webkit-backface-visibility: hidden;
70
+ }
71
+ /**
72
+ * The frame that bounds the box contents of the picker.
73
+ */
74
+ .picker__frame {
75
+ position: absolute;
76
+ margin: 0 auto;
77
+ min-width: 256px;
78
+ max-width: 666px;
79
+ width: 100%;
80
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
81
+ filter: alpha(opacity=0);
82
+ -moz-opacity: 0;
83
+ opacity: 0;
84
+ -webkit-transition: all 0.15s ease-out;
85
+ transition: all 0.15s ease-out;
86
+ }
87
+ @media (min-height: 33.875em) {
88
+ .picker__frame {
89
+ overflow: visible;
90
+ top: auto;
91
+ bottom: -100%;
92
+ max-height: 80%;
93
+ }
94
+ }
95
+ @media (min-height: 40.125em) {
96
+ .picker__frame {
97
+ margin-bottom: 7.5%;
98
+ }
99
+ }
100
+ /**
101
+ * The wrapper sets the stage to vertically align the box contents.
102
+ */
103
+ .picker__wrap {
104
+ display: table;
105
+ width: 100%;
106
+ height: 100%;
107
+ }
108
+ @media (min-height: 33.875em) {
109
+ .picker__wrap {
110
+ display: block;
111
+ }
112
+ }
113
+ /**
114
+ * The box contains all the picker contents.
115
+ */
116
+ .picker__box {
117
+ background: #ffffff;
118
+ display: table-cell;
119
+ vertical-align: middle;
120
+ }
121
+ @media (min-height: 26.5em) {
122
+ .picker__box {
123
+ font-size: 1.25em;
124
+ }
125
+ }
126
+ @media (min-height: 33.875em) {
127
+ .picker__box {
128
+ display: block;
129
+ font-size: 1.33em;
130
+ border: 1px solid #777777;
131
+ border-top-color: #898989;
132
+ border-bottom-width: 0;
133
+ border-radius: 5px 5px 0 0;
134
+ box-shadow: 0 12px 36px 16px rgba(0, 0, 0, 0.24);
135
+ }
136
+ }
137
+ @media (min-height: 40.125em) {
138
+ .picker__box {
139
+ font-size: 1.5em;
140
+ border-bottom-width: 1px;
141
+ border-radius: 5px;
142
+ }
143
+ }
144
+ /**
145
+ * When the picker opens...
146
+ */
147
+ .picker--opened .picker__holder {
148
+ -webkit-transform: translateY(0);
149
+ -ms-transform: translateY(0);
150
+ transform: translateY(0);
151
+ background: transparent;
152
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)";
153
+ zoom: 1;
154
+ background: rgba(0, 0, 0, 0.32);
155
+ -webkit-transition: background 0.15s ease-out;
156
+ transition: background 0.15s ease-out;
157
+ }
158
+ .picker--opened .picker__frame {
159
+ -webkit-transform: translateY(0);
160
+ -ms-transform: translateY(0);
161
+ transform: translateY(0);
162
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
163
+ filter: alpha(opacity=100);
164
+ -moz-opacity: 1;
165
+ opacity: 1;
166
+ }
167
+ @media (min-height: 33.875em) {
168
+ .picker--opened .picker__frame {
169
+ top: auto;
170
+ bottom: 0;
171
+ }
172
+ }
lib/simple-admin-pages/lib/pickadate/themes/default.date.css CHANGED
@@ -1 +1,301 @@
1
- .picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{font-weight:500;display:inline-block;margin-left:.25em;margin-right:.25em}.picker__year{color:#999;font-size:.8em;font-style:italic}.picker__select--month,.picker__select--year{border:1px solid #b7b7b7;height:2em;padding:.5em;margin-left:.25em;margin-right:.25em}@media (min-width:24.5em){.picker__select--month,.picker__select--year{margin-top:-.5em}}.picker__select--month{width:35%}.picker__select--year{width:22.5%}.picker__select--month:focus,.picker__select--year:focus{border-color:#0089ec}.picker__nav--next,.picker__nav--prev{position:absolute;padding:.5em 1.25em;width:1em;height:1em;top:-.25em}@media (min-width:24.5em){.picker__nav--next,.picker__nav--prev{top:-.33em}}.picker__nav--prev{left:-1em;padding-right:1.25em}@media (min-width:24.5em){.picker__nav--prev{padding-right:1.5em}}.picker__nav--next{right:-1em;padding-left:1.25em}@media (min-width:24.5em){.picker__nav--next{padding-left:1.5em}}.picker__nav--next:before,.picker__nav--prev:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:.75em solid #000;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:.75em solid #000}.picker__nav--next:hover,.picker__nav--prev:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker__nav--disabled,.picker__nav--disabled:before,.picker__nav--disabled:before:hover,.picker__nav--disabled:hover{cursor:default;background:0 0;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:inherit;width:100%;margin-top:.75em;margin-bottom:.5em}@media (min-height:33.875em){.picker__table{margin-bottom:.75em}}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999;font-weight:500}@media (min-height:33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day{padding:.3125em 0;font-weight:200;border:1px solid transparent}.picker__day--today{color:#0089ec;position:relative}.picker__day--today:before{content:" ";position:absolute;top:2px;right:2px;width:0;height:0;border-top:.5em solid #0059bc;border-left:.5em solid transparent}.picker__day--selected,.picker__day--selected:hover{border-color:#0089ec}.picker__day--highlighted{background:#b1dcfb}.picker__day--disabled:before{border-top-color:#aaa}.picker__day--outfocus{color:#ddd}.picker__day--infocus:hover,.picker__day--outfocus:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker--focused .picker__day--highlighted,.picker__day--highlighted:hover{background:#0089ec;color:#fff}.picker__day--disabled,.picker__day--disabled:hover{background:#f5f5f5;border-color:#f5f5f5;color:#ddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbb}.picker__footer{text-align:center}.picker__button--clear,.picker__button--today{border:1px solid #fff;background:#fff;font-size:.8em;padding:.66em 0;font-weight:700;width:50%;display:inline-block;vertical-align:bottom}.picker__button--clear:hover,.picker__button--today:hover{cursor:pointer;color:#000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--clear:focus,.picker__button--today:focus{background:#b1dcfb;border-color:#0089ec;outline:0}.picker__button--clear:before,.picker__button--today:before{position:relative;display:inline-block;height:0}.picker__button--today:before{content:" ";margin-right:.45em;top:-.05em;width:0;border-top:.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{content:"\D7";margin-right:.35em;top:-.1em;color:#e20;vertical-align:top;font-size:1.1em}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ==========================================================================
2
+ $BASE-DATE-PICKER
3
+ ========================================================================== */
4
+ /**
5
+ * The picker box.
6
+ */
7
+ .picker__box {
8
+ padding: 0 1em;
9
+ }
10
+ /**
11
+ * The header containing the month and year stuff.
12
+ */
13
+ .picker__header {
14
+ text-align: center;
15
+ position: relative;
16
+ margin-top: .75em;
17
+ }
18
+ /**
19
+ * The month and year labels.
20
+ */
21
+ .picker__month,
22
+ .picker__year {
23
+ font-weight: 500;
24
+ display: inline-block;
25
+ margin-left: .25em;
26
+ margin-right: .25em;
27
+ }
28
+ .picker__year {
29
+ color: #999999;
30
+ font-size: .8em;
31
+ font-style: italic;
32
+ }
33
+ /**
34
+ * The month and year selectors.
35
+ */
36
+ .picker__select--month,
37
+ .picker__select--year {
38
+ border: 1px solid #b7b7b7;
39
+ height: 2em;
40
+ padding: .5em;
41
+ margin-left: .25em;
42
+ margin-right: .25em;
43
+ }
44
+ @media (min-width: 24.5em) {
45
+ .picker__select--month,
46
+ .picker__select--year {
47
+ margin-top: -0.5em;
48
+ }
49
+ }
50
+ .picker__select--month {
51
+ width: 35%;
52
+ }
53
+ .picker__select--year {
54
+ width: 22.5%;
55
+ }
56
+ .picker__select--month:focus,
57
+ .picker__select--year:focus {
58
+ border-color: #0089ec;
59
+ }
60
+ /**
61
+ * The month navigation buttons.
62
+ */
63
+ .picker__nav--prev,
64
+ .picker__nav--next {
65
+ position: absolute;
66
+ padding: .5em 1.25em;
67
+ width: 1em;
68
+ height: 1em;
69
+ box-sizing: content-box;
70
+ top: -0.25em;
71
+ }
72
+ @media (min-width: 24.5em) {
73
+ .picker__nav--prev,
74
+ .picker__nav--next {
75
+ top: -0.33em;
76
+ }
77
+ }
78
+ .picker__nav--prev {
79
+ left: -1em;
80
+ padding-right: 1.25em;
81
+ }
82
+ @media (min-width: 24.5em) {
83
+ .picker__nav--prev {
84
+ padding-right: 1.5em;
85
+ }
86
+ }
87
+ .picker__nav--next {
88
+ right: -1em;
89
+ padding-left: 1.25em;
90
+ }
91
+ @media (min-width: 24.5em) {
92
+ .picker__nav--next {
93
+ padding-left: 1.5em;
94
+ }
95
+ }
96
+ .picker__nav--prev:before,
97
+ .picker__nav--next:before {
98
+ content: " ";
99
+ border-top: .5em solid transparent;
100
+ border-bottom: .5em solid transparent;
101
+ border-right: 0.75em solid #000000;
102
+ width: 0;
103
+ height: 0;
104
+ display: block;
105
+ margin: 0 auto;
106
+ }
107
+ .picker__nav--next:before {
108
+ border-right: 0;
109
+ border-left: 0.75em solid #000000;
110
+ }
111
+ .picker__nav--prev:hover,
112
+ .picker__nav--next:hover {
113
+ cursor: pointer;
114
+ color: #000000;
115
+ background: #b1dcfb;
116
+ }
117
+ .picker__nav--disabled,
118
+ .picker__nav--disabled:hover,
119
+ .picker__nav--disabled:before,
120
+ .picker__nav--disabled:before:hover {
121
+ cursor: default;
122
+ background: none;
123
+ border-right-color: #f5f5f5;
124
+ border-left-color: #f5f5f5;
125
+ }
126
+ /**
127
+ * The calendar table of dates
128
+ */
129
+ .picker__table {
130
+ text-align: center;
131
+ border-collapse: collapse;
132
+ border-spacing: 0;
133
+ table-layout: fixed;
134
+ font-size: inherit;
135
+ width: 100%;
136
+ margin-top: .75em;
137
+ margin-bottom: .5em;
138
+ }
139
+ @media (min-height: 33.875em) {
140
+ .picker__table {
141
+ margin-bottom: .75em;
142
+ }
143
+ }
144
+ .picker__table td {
145
+ margin: 0;
146
+ padding: 0;
147
+ }
148
+ /**
149
+ * The weekday labels
150
+ */
151
+ .picker__weekday {
152
+ width: 14.285714286%;
153
+ font-size: .75em;
154
+ padding-bottom: .25em;
155
+ color: #999999;
156
+ font-weight: 500;
157
+ /* Increase the spacing a tad */
158
+ }
159
+ @media (min-height: 33.875em) {
160
+ .picker__weekday {
161
+ padding-bottom: .5em;
162
+ }
163
+ }
164
+ /**
165
+ * The days on the calendar
166
+ */
167
+ .picker__day {
168
+ padding: .3125em 0;
169
+ font-weight: 200;
170
+ border: 1px solid transparent;
171
+ }
172
+ .picker__day--today {
173
+ position: relative;
174
+ }
175
+ .picker__day--today:before {
176
+ content: " ";
177
+ position: absolute;
178
+ top: 2px;
179
+ right: 2px;
180
+ width: 0;
181
+ height: 0;
182
+ border-top: 0.5em solid #0059bc;
183
+ border-left: .5em solid transparent;
184
+ }
185
+ .picker__day--disabled:before {
186
+ border-top-color: #aaaaaa;
187
+ }
188
+ .picker__day--outfocus {
189
+ color: #dddddd;
190
+ }
191
+ .picker__day--infocus:hover,
192
+ .picker__day--outfocus:hover {
193
+ cursor: pointer;
194
+ color: #000000;
195
+ background: #b1dcfb;
196
+ }
197
+ .picker__day--highlighted {
198
+ border-color: #0089ec;
199
+ }
200
+ .picker__day--highlighted:hover,
201
+ .picker--focused .picker__day--highlighted {
202
+ cursor: pointer;
203
+ color: #000000;
204
+ background: #b1dcfb;
205
+ }
206
+ .picker__day--selected,
207
+ .picker__day--selected:hover,
208
+ .picker--focused .picker__day--selected {
209
+ background: #0089ec;
210
+ color: #ffffff;
211
+ }
212
+ .picker__day--disabled,
213
+ .picker__day--disabled:hover,
214
+ .picker--focused .picker__day--disabled {
215
+ background: #f5f5f5;
216
+ border-color: #f5f5f5;
217
+ color: #dddddd;
218
+ cursor: default;
219
+ }
220
+ .picker__day--highlighted.picker__day--disabled,
221
+ .picker__day--highlighted.picker__day--disabled:hover {
222
+ background: #bbbbbb;
223
+ }
224
+ /**
225
+ * The footer containing the "today", "clear", and "close" buttons.
226
+ */
227
+ .picker__footer {
228
+ text-align: center;
229
+ }
230
+ .picker__button--today,
231
+ .picker__button--clear,
232
+ .picker__button--close {
233
+ border: 1px solid #ffffff;
234
+ background: #ffffff;
235
+ font-size: .8em;
236
+ padding: .66em 0;
237
+ font-weight: bold;
238
+ width: 33%;
239
+ display: inline-block;
240
+ vertical-align: bottom;
241
+ }
242
+ .picker__button--today:hover,
243
+ .picker__button--clear:hover,
244
+ .picker__button--close:hover {
245
+ cursor: pointer;
246
+ color: #000000;
247
+ background: #b1dcfb;
248
+ border-bottom-color: #b1dcfb;
249
+ }
250
+ .picker__button--today:focus,
251
+ .picker__button--clear:focus,
252
+ .picker__button--close:focus {
253
+ background: #b1dcfb;
254
+ border-color: #0089ec;
255
+ outline: none;
256
+ }
257
+ .picker__button--today:before,
258
+ .picker__button--clear:before,
259
+ .picker__button--close:before {
260
+ position: relative;
261
+ display: inline-block;
262
+ height: 0;
263
+ }
264
+ .picker__button--today:before,
265
+ .picker__button--clear:before {
266
+ content: " ";
267
+ margin-right: .45em;
268
+ }
269
+ .picker__button--today:before {
270
+ top: -0.05em;
271
+ width: 0;
272
+ border-top: 0.66em solid #0059bc;
273
+ border-left: .66em solid transparent;
274
+ }
275
+ .picker__button--clear:before {
276
+ top: -0.25em;
277
+ width: .66em;
278
+ border-top: 3px solid #ee2200;
279
+ }
280
+ .picker__button--close:before {
281
+ content: "\D7";
282
+ top: -0.1em;
283
+ vertical-align: top;
284
+ font-size: 1.1em;
285
+ margin-right: .35em;
286
+ color: #777777;
287
+ }
288
+ .picker__button--today[disabled],
289
+ .picker__button--today[disabled]:hover {
290
+ background: #f5f5f5;
291
+ border-color: #f5f5f5;
292
+ color: #dddddd;
293
+ cursor: default;
294
+ }
295
+ .picker__button--today[disabled]:before {
296
+ border-top-color: #aaaaaa;
297
+ }
298
+
299
+ /* ==========================================================================
300
+ $DEFAULT-DATE-PICKER
301
+ ========================================================================== */
lib/simple-admin-pages/lib/pickadate/themes/default.time.css CHANGED
@@ -1 +1,126 @@
1
- .picker__list{list-style:none;padding:.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #ddd;border-top:1px solid #ddd;margin-bottom:-1px;position:relative;background:#fff;padding:.75em 1.25em}@media (min-height:46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--selected,.picker__list-item--selected:hover{border-color:#0089ec;z-index:10}.picker__list-item--highlighted{background:#b1dcfb}.picker--focused .picker__list-item--highlighted,.picker__list-item--highlighted:hover{background:#0089ec;color:#fff}.picker--focused .picker__list-item--disabled,.picker__list-item--disabled,.picker__list-item--disabled:hover{background:#f5f5f5;color:#ddd;cursor:default;border-color:#ddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:0 0;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:focus,.picker--time .picker__button--clear:hover{background:#b1dcfb;background:#e20;border-color:#e20;cursor:pointer;color:#fff;outline:0}.picker--time .picker__button--clear:before{top:-.25em;color:#666;font-size:1.25em;font-weight:700}.picker--time .picker__button--clear:focus:before,.picker--time .picker__button--clear:hover:before{color:#fff}.picker--time .picker__frame{min-width:256px;max-width:320px}.picker--time .picker__box{font-size:1em;background:#f2f2f2;padding:0}@media (min-height:40.125em){.picker--time .picker__box{margin-bottom:5em}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ==========================================================================
2
+ $BASE-TIME-PICKER
3
+ ========================================================================== */
4
+ /**
5
+ * The list of times.
6
+ */
7
+ .picker__list {
8
+ list-style: none;
9
+ padding: 0.75em 0 4.2em;
10
+ margin: 0;
11
+ }
12
+ /**
13
+ * The times on the clock.
14
+ */
15
+ .picker__list-item {
16
+ border-bottom: 1px solid #dddddd;
17
+ border-top: 1px solid #dddddd;
18
+ margin-bottom: -1px;
19
+ position: relative;
20
+ background: #ffffff;
21
+ padding: .75em 1.25em;
22
+ }
23
+ @media (min-height: 46.75em) {
24
+ .picker__list-item {
25
+ padding: .5em 1em;
26
+ }
27
+ }
28
+ /* Hovered time */
29
+ .picker__list-item:hover {
30
+ cursor: pointer;
31
+ color: #000000;
32
+ background: #b1dcfb;
33
+ border-color: #0089ec;
34
+ z-index: 10;
35
+ }
36
+ /* Highlighted and hovered/focused time */
37
+ .picker__list-item--highlighted {
38
+ border-color: #0089ec;
39
+ z-index: 10;
40
+ }
41
+ .picker__list-item--highlighted:hover,
42
+ .picker--focused .picker__list-item--highlighted {
43
+ cursor: pointer;
44
+ color: #000000;
45
+ background: #b1dcfb;
46
+ }
47
+ /* Selected and hovered/focused time */
48
+ .picker__list-item--selected,
49
+ .picker__list-item--selected:hover,
50
+ .picker--focused .picker__list-item--selected {
51
+ background: #0089ec;
52
+ color: #ffffff;
53
+ z-index: 10;
54
+ }
55
+ /* Disabled time */
56
+ .picker__list-item--disabled,
57
+ .picker__list-item--disabled:hover,
58
+ .picker--focused .picker__list-item--disabled {
59
+ background: #f5f5f5;
60
+ border-color: #f5f5f5;
61
+ color: #dddddd;
62
+ cursor: default;
63
+ border-color: #dddddd;
64
+ z-index: auto;
65
+ }
66
+ /**
67
+ * The clear button
68
+ */
69
+ .picker--time .picker__button--clear {
70
+ display: block;
71
+ width: 80%;
72
+ margin: 1em auto 0;
73
+ padding: 1em 1.25em;
74
+ background: none;
75
+ border: 0;
76
+ font-weight: 500;
77
+ font-size: .67em;
78
+ text-align: center;
79
+ text-transform: uppercase;
80
+ color: #666;
81
+ }
82
+ .picker--time .picker__button--clear:hover,
83
+ .picker--time .picker__button--clear:focus {
84
+ color: #000000;
85
+ background: #b1dcfb;
86
+ background: #ee2200;
87
+ border-color: #ee2200;
88
+ cursor: pointer;
89
+ color: #ffffff;
90
+ outline: none;
91
+ }
92
+ .picker--time .picker__button--clear:before {
93
+ top: -0.25em;
94
+ color: #666;
95
+ font-size: 1.25em;
96
+ font-weight: bold;
97
+ }
98
+ .picker--time .picker__button--clear:hover:before,
99
+ .picker--time .picker__button--clear:focus:before {
100
+ color: #ffffff;
101
+ border-color: #ffffff;
102
+ }
103
+
104
+ /* ==========================================================================
105
+ $DEFAULT-TIME-PICKER
106
+ ========================================================================== */
107
+ /**
108
+ * The frame the bounds the time picker.
109
+ */
110
+ .picker--time .picker__frame {
111
+ min-width: 256px;
112
+ max-width: 320px;
113
+ }
114
+ /**
115
+ * The picker box.
116
+ */
117
+ .picker--time .picker__box {
118
+ font-size: 1em;
119
+ background: #f2f2f2;
120
+ padding: 0;
121
+ }
122
+ @media (min-height: 40.125em) {
123
+ .picker--time .picker__box {
124
+ margin-bottom: 5em;
125
+ }
126
+ }
lib/simple-admin-pages/lib/pickadate/themes/rtl.css CHANGED
@@ -1,3 +1,29 @@
1
  /*!
2
  * Styling for RTL (right-to-left) languages using pickadate.js
3
- */.picker{direction:rtl}.picker__nav--next{right:auto;left:-1em}.picker__nav--prev{left:auto;right:-1em}.picker__nav--next:before{border-left:0;border-right:.75em solid #000}.picker__nav--prev:before{border-right:0;border-left:.75em solid #000}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /*!
2
  * Styling for RTL (right-to-left) languages using pickadate.js
3
+ */
4
+ /**
5
+ * Switch the direction - only really necessary if
6
+ * it hasn’t already been applied higher up in the DOM.
7
+ */
8
+ .picker {
9
+ direction: rtl;
10
+ }
11
+ /**
12
+ * Flip around the “next” and “previous” buttons.
13
+ */
14
+ .picker__nav--next {
15
+ right: auto;
16
+ left: -1em;
17
+ }
18
+ .picker__nav--prev {
19
+ left: auto;
20
+ right: -1em;
21
+ }
22
+ .picker__nav--next:before {
23
+ border-left: 0;
24
+ border-right: 0.75em solid #000000;
25
+ }
26
+ .picker__nav--prev:before {
27
+ border-right: 0;
28
+ border-left: 0.75em solid #000000;
29
+ }
lib/simple-admin-pages/lib/pickadate/translations/ca_ES.js CHANGED
@@ -7,6 +7,7 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
7
  weekdaysShort: [ 'diu', 'dil', 'dim', 'dmc', 'dij', 'div', 'dis' ],
8
  today: 'avui',
9
  clear: 'esborrar',
 
10
  firstDay: 1,
11
  format: 'dddd d !de mmmm !de yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
7
  weekdaysShort: [ 'diu', 'dil', 'dim', 'dmc', 'dij', 'div', 'dis' ],
8
  today: 'avui',
9
  clear: 'esborrar',
10
+ close: 'tancar',
11
  firstDay: 1,
12
  format: 'dddd d !de mmmm !de yyyy',
13
  formatSubmit: 'yyyy/mm/dd'
lib/simple-admin-pages/lib/pickadate/translations/da_DK.js CHANGED
@@ -7,6 +7,7 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
7
  weekdaysShort: [ 'søn', 'man', 'tir', 'ons', 'tor', 'fre', 'lør' ],
8
  today: 'i dag',
9
  clear: 'slet',
 
10
  firstDay: 1,
11
  format: 'd. mmmm yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
7
  weekdaysShort: [ 'søn', 'man', 'tir', 'ons', 'tor', 'fre', 'lør' ],
8
  today: 'i dag',
9
  clear: 'slet',
10
+ close: 'luk',
11
  firstDay: 1,
12
  format: 'd. mmmm yyyy',
13
  formatSubmit: 'yyyy/mm/dd'
lib/simple-admin-pages/lib/pickadate/translations/de_DE.js CHANGED
@@ -7,6 +7,7 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
7
  weekdaysShort: [ 'So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa' ],
8
  today: 'Heute',
9
  clear: 'Löschen',
 
10
  firstDay: 1,
11
  format: 'dddd, dd. mmmm yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
7
  weekdaysShort: [ 'So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa' ],
8
  today: 'Heute',
9
  clear: 'Löschen',
10
+ close: 'Schließen',
11
  firstDay: 1,
12
  format: 'dddd, dd. mmmm yyyy',
13
  formatSubmit: 'yyyy/mm/dd'
lib/simple-admin-pages/lib/pickadate/translations/fr_FR.js CHANGED
@@ -11,10 +11,10 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
11
  firstDay: 1,
12
  format: 'dd mmmm yyyy',
13
  formatSubmit: 'yyyy/mm/dd',
14
- labelMonthNext: 'Mois suivant',
15
- labelMonthPrev: 'Mois précédent',
16
- labelMonthSelect: 'Sélectionner un mois',
17
- labelYearSelect: 'Sélectionner une année'
18
  });
19
 
20
  jQuery.extend( jQuery.fn.pickatime.defaults, {
11
  firstDay: 1,
12
  format: 'dd mmmm yyyy',
13
  formatSubmit: 'yyyy/mm/dd',
14
+ labelMonthNext:"Mois suivant",
15
+ labelMonthPrev:"Mois précédent",
16
+ labelMonthSelect:"Sélectionner un mois",
17
+ labelYearSelect:"Sélectionner une année"
18
  });
19
 
20
  jQuery.extend( jQuery.fn.pickatime.defaults, {
lib/simple-admin-pages/lib/pickadate/translations/it_IT.js CHANGED
@@ -3,16 +3,22 @@
3
  jQuery.extend( jQuery.fn.pickadate.defaults, {
4
  monthsFull: [ 'gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre' ],
5
  monthsShort: [ 'gen', 'feb', 'mar', 'apr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic' ],
6
- weekdaysFull: [ 'domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato' ],
7
  weekdaysShort: [ 'dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab' ],
8
  today: 'Oggi',
9
- clear: 'Cancellare',
10
  close: 'Chiudi',
11
  firstDay: 1,
12
  format: 'dddd d mmmm yyyy',
13
- formatSubmit: 'yyyy/mm/dd'
 
 
 
 
14
  });
15
 
16
  jQuery.extend( jQuery.fn.pickatime.defaults, {
17
- clear: 'Cancellare'
 
 
18
  });
3
  jQuery.extend( jQuery.fn.pickadate.defaults, {
4
  monthsFull: [ 'gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre' ],
5
  monthsShort: [ 'gen', 'feb', 'mar', 'apr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic' ],
6
+ weekdaysFull: [ 'domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato' ],
7
  weekdaysShort: [ 'dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab' ],
8
  today: 'Oggi',
9
+ clear: 'Cancella',
10
  close: 'Chiudi',
11
  firstDay: 1,
12
  format: 'dddd d mmmm yyyy',
13
+ formatSubmit: 'yyyy/mm/dd',
14
+ labelMonthNext: 'Mese successivo',
15
+ labelMonthPrev: 'Mese precedente',
16
+ labelMonthSelect: 'Seleziona un mese',
17
+ labelYearSelect: 'Seleziona un anno'
18
  });
19
 
20
  jQuery.extend( jQuery.fn.pickatime.defaults, {
21
+ clear: 'Cancella',
22
+ format: 'HH:i',
23
+ formatSubmit: 'HH:i'
24
  });
lib/simple-admin-pages/lib/pickadate/translations/lt_LT.js ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Lietuviškai
2
+
3
+ jQuery.extend( jQuery.fn.pickadate.defaults, {
4
+ labelMonthNext: 'Sekantis mėnuo',
5
+ labelMonthPrev: 'Ankstesnis mėnuo',
6
+ labelMonthSelect: 'Pasirinkite mėnesį',
7
+ labelYearSelect: 'Pasirinkite metus',
8
+ monthsFull: ['Sausis', 'Vasaris', 'Kovas', 'Balandis', 'Gegužė', 'Birželis', 'Liepa', 'Rugpjūtis', 'Rugsėjis', 'Spalis', 'Lapkritis', 'Gruodis'],
9
+ monthsShort: ['Sau', 'Vas', 'Kov', 'Bal', 'Geg', 'Bir', 'Lie', 'Rgp', 'Rgs', 'Spa', 'Lap', 'Grd'],
10
+ weekdaysFull: ['Sekmadienis', 'Pirmadienis', 'Antradienis', 'Trečiadienis', 'Ketvirtadienis', 'Penktadienis', 'Šeštadienis'],
11
+ weekdaysShort: ['Sk', 'Pr', 'An', 'Tr', 'Kt', 'Pn', 'Št'],
12
+ today: 'Šiandien',
13
+ clear: 'Išvalyti',
14
+ close: 'Uždaryti',
15
+ firstDay: 1,
16
+ //format: 'yyyy !m. mmmm d !d.', // need to have diffrent case of full months name
17
+ format: 'yyyy-mm-dd',
18
+ formatSubmit: 'yyyy/mm/dd'
19
+ });
20
+
21
+ jQuery.extend( jQuery.fn.pickatime.defaults, {
22
+ clear: 'Išvalyti',
23
+ format: 'HH:i'
24
+ });
lib/simple-admin-pages/lib/pickadate/translations/lv_LV.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Latvian
2
+
3
+ jQuery.extend( jQuery.fn.pickadate.defaults, {
4
+ monthsFull: [ 'Janvāris', 'Februāris', 'Marts', 'Aprīlis', 'Maijs', 'Jūnijs', 'Jūlijs', 'Augusts', 'Septembris', 'Oktobris', 'Novembris', 'Decembris' ],
5
+ monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jūn', 'Jūl', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec' ],
6
+ weekdaysFull: [ 'Svētdiena', 'Pirmdiena', 'Otrdiena', 'Trešdiena', 'Ceturtdiena', 'Piektdiena', 'Sestdiena' ],
7
+ weekdaysShort: [ 'Sv', 'P', 'O', 'T', 'C', 'Pk', 'S' ],
8
+ today: 'Šodiena',
9
+ clear: 'Atcelt',
10
+ firstDay: 1,
11
+ format: 'yyyy.mm.dd. dddd',
12
+ formatSubmit: 'yyyy/mm/dd'
13
+ });
lib/simple-admin-pages/lib/pickadate/translations/{no_NO.js → nb_NO.js} RENAMED
@@ -7,6 +7,7 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
7
  weekdaysShort: [ 'søn','man','tir', 'ons', 'tor', 'fre', 'lør' ],
8
  today: 'i dag',
9
  clear: 'nullstill',
 
10
  firstDay: 1,
11
  format: 'dd. mmm. yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
7
  weekdaysShort: [ 'søn','man','tir', 'ons', 'tor', 'fre', 'lør' ],
8
  today: 'i dag',
9
  clear: 'nullstill',
10
+ close: 'lukk',
11
  firstDay: 1,
12
  format: 'dd. mmm. yyyy',
13
  formatSubmit: 'yyyy/mm/dd'
lib/simple-admin-pages/lib/pickadate/translations/nl_NL.js CHANGED
@@ -7,6 +7,7 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
7
  weekdaysShort: [ 'zo', 'ma', 'di', 'wo', 'do', 'vr', 'za' ],
8
  today: 'vandaag',
9
  clear: 'verwijderen',
 
10
  firstDay: 1,
11
  format: 'dddd d mmmm yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
7
  weekdaysShort: [ 'zo', 'ma', 'di', 'wo', 'do', 'vr', 'za' ],
8
  today: 'vandaag',
9
  clear: 'verwijderen',
10
+ close: 'sluiten',
11
  firstDay: 1,
12
  format: 'dddd d mmmm yyyy',
13
  formatSubmit: 'yyyy/mm/dd'
lib/simple-admin-pages/lib/pickadate/translations/pl_PL.js CHANGED
@@ -4,9 +4,10 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
4
  monthsFull: [ 'styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec', 'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień' ],
5
  monthsShort: [ 'sty', 'lut', 'mar', 'kwi', 'maj', 'cze', 'lip', 'sie', 'wrz', 'paź', 'lis', 'gru' ],
6
  weekdaysFull: [ 'niedziela', 'poniedziałek', 'wtorek', 'środa', 'czwartek', 'piątek', 'sobota' ],
7
- weekdaysShort: [ 'N', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So' ],
8
- today: 'dzisiaj',
9
- clear: 'usunąć',
 
10
  firstDay: 1,
11
  format: 'd mmmm yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
4
  monthsFull: [ 'styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec', 'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień' ],
5
  monthsShort: [ 'sty', 'lut', 'mar', 'kwi', 'maj', 'cze', 'lip', 'sie', 'wrz', 'paź', 'lis', 'gru' ],
6
  weekdaysFull: [ 'niedziela', 'poniedziałek', 'wtorek', 'środa', 'czwartek', 'piątek', 'sobota' ],
7
+ weekdaysShort: [ 'niedz.', 'pn.', 'wt.', 'śr.', 'cz.', 'pt.', 'sob.' ],
8
+ today: 'Dzisiaj',
9
+ clear: 'Usuń',
10
+ close: 'Zamknij',
11
  firstDay: 1,
12
  format: 'd mmmm yyyy',
13
  formatSubmit: 'yyyy/mm/dd'
lib/simple-admin-pages/lib/pickadate/translations/pt_BR.js CHANGED
@@ -6,11 +6,12 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
6
  weekdaysFull: [ 'domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado' ],
7
  weekdaysShort: [ 'dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab' ],
8
  today: 'hoje',
9
- clear: 'excluir',
 
10
  format: 'dddd, d !de mmmm !de yyyy',
11
  formatSubmit: 'yyyy/mm/dd'
12
  });
13
 
14
  jQuery.extend( jQuery.fn.pickatime.defaults, {
15
- clear: 'excluir'
16
  });
6
  weekdaysFull: [ 'domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado' ],
7
  weekdaysShort: [ 'dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab' ],
8
  today: 'hoje',
9
+ clear: 'limpar',
10
+ close: 'fechar',
11
  format: 'dddd, d !de mmmm !de yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
13
  });
14
 
15
  jQuery.extend( jQuery.fn.pickatime.defaults, {
16
+ clear: 'limpar'
17
  });
lib/simple-admin-pages/lib/pickadate/translations/pt_PT.js CHANGED
@@ -1,16 +1,17 @@
1
  // Portuguese
2
 
3
  jQuery.extend( jQuery.fn.pickadate.defaults, {
4
- monthsFull: [ 'janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro' ],
5
  monthsShort: [ 'jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez' ],
6
- weekdaysFull: [ 'domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado' ],
7
  weekdaysShort: [ 'dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab' ],
8
- today: 'hoje',
9
- clear: 'excluir',
 
10
  format: 'd !de mmmm !de yyyy',
11
  formatSubmit: 'yyyy/mm/dd'
12
  });
13
 
14
  jQuery.extend( jQuery.fn.pickatime.defaults, {
15
- clear: 'excluir'
16
  });
1
  // Portuguese
2
 
3
  jQuery.extend( jQuery.fn.pickadate.defaults, {
4
+ monthsFull: [ 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro' ],
5
  monthsShort: [ 'jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez' ],
6
+ weekdaysFull: [ 'Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado' ],
7
  weekdaysShort: [ 'dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab' ],
8
+ today: 'Hoje',
9
+ clear: 'Limpar',
10
+ close: 'Fechar',
11
  format: 'd !de mmmm !de yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
13
  });
14
 
15
  jQuery.extend( jQuery.fn.pickatime.defaults, {
16
+ clear: 'Limpar'
17
  });
lib/simple-admin-pages/lib/pickadate/translations/sl_SI.js CHANGED
@@ -7,6 +7,7 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
7
  weekdaysShort: [ 'ned', 'pon', 'tor', 'sre', 'čet', 'pet', 'sob' ],
8
  today: 'danes',
9
  clear: 'izbriši',
 
10
  firstDay: 1,
11
  format: 'd. mmmm yyyy',
12
  formatSubmit: 'yyyy/mm/dd'
7
  weekdaysShort: [ 'ned', 'pon', 'tor', 'sre', 'čet', 'pet', 'sob' ],
8
  today: 'danes',
9
  clear: 'izbriši',
10
+ close: 'zapri',
11
  firstDay: 1,
12
  format: 'd. mmmm yyyy',
13
  formatSubmit: 'yyyy/mm/dd'
lib/simple-admin-pages/lib/pickadate/translations/sv_SE.js CHANGED
@@ -5,13 +5,18 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
5
  monthsShort: [ 'jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec' ],
6
  weekdaysFull: [ 'söndag', 'måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag' ],
7
  weekdaysShort: [ 'sön', 'mån', 'tis', 'ons', 'tor', 'fre', 'lör' ],
8
- today: 'i dag',
9
- clear: 'bort',
 
10
  firstDay: 1,
11
- format: 'd/m yyyy',
12
- formatSubmit: 'yyyy/mm/dd'
 
 
 
 
13
  });
14
 
15
  jQuery.extend( jQuery.fn.pickatime.defaults, {
16
- clear: 'bort'
17
  });
5
  monthsShort: [ 'jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec' ],
6
  weekdaysFull: [ 'söndag', 'måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag' ],
7
  weekdaysShort: [ 'sön', 'mån', 'tis', 'ons', 'tor', 'fre', 'lör' ],
8
+ today: 'Idag',
9
+ clear: 'Rensa',
10
+ close: 'Stäng',
11
  firstDay: 1,
12
+ format: 'yyyy-mm-dd',
13
+ formatSubmit: 'yyyy/mm/dd',
14
+ labelMonthNext: 'Nästa månad',
15
+ labelMonthPrev: 'Föregående månad',
16
+ labelMonthSelect: 'Välj månad',
17
+ labelYearSelect: 'Välj år'
18
  });
19
 
20
  jQuery.extend( jQuery.fn.pickatime.defaults, {
21
+ clear: 'Rensa'
22
  });
lib/simple-admin-pages/lib/pickadate/translations/tr_TR.js CHANGED
@@ -5,8 +5,9 @@ jQuery.extend( jQuery.fn.pickadate.defaults, {
5
  monthsShort: [ 'Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara' ],
6
  weekdaysFull: [ 'Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi' ],
7
  weekdaysShort: [ 'Pzr', 'Pzt', 'Sal', 'Çrş', 'Prş', 'Cum', 'Cmt' ],
8
- today: 'bugün',
9
- clear: 'sil',
 
10
  firstDay: 1,
11
  format: 'dd mmmm yyyy dddd',
12
  formatSubmit: 'yyyy/mm/dd'
5
  monthsShort: [ 'Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara' ],
6
  weekdaysFull: [ 'Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi' ],
7
  weekdaysShort: [ 'Pzr', 'Pzt', 'Sal', 'Çrş', 'Prş', 'Cum', 'Cmt' ],
8
+ today: 'Bugün',
9
+ clear: 'Sil',
10
+ close: 'Kapat',
11
  firstDay: 1,
12
  format: 'dd mmmm yyyy dddd',
13
  formatSubmit: 'yyyy/mm/dd'
lib/simple-admin-pages/simple-admin-pages.php CHANGED
@@ -44,11 +44,6 @@ if ( !function_exists( 'sap_initialize_library' ) ) {
44
  return null;
45
  }
46
 
47
- // Set the textdomain for translation
48
- if ( !defined( 'SAP_TEXTDOMAIN' ) ) {
49
- define( 'SAP_TEXTDOMAIN', 'sapdomain' );
50
- }
51
-
52
  $lib_class_name = 'sapLibrary_' . str_replace( '.', '_', $args['version'] );
53
 
54
  return new $lib_class_name( $args );
44
  return null;
45
  }
46
 
 
 
 
 
 
47
  $lib_class_name = 'sapLibrary_' . str_replace( '.', '_', $args['version'] );
48
 
49
  return new $lib_class_name( $args );
readme.txt CHANGED
@@ -5,7 +5,7 @@ Plugin URL: http://themeofthecrop.com
5
  Requires at Least: 3.8
6
  Tested Up To: 4.1
7
  Tags: restaurant, reservations, bookings, table bookings, restaurant reservation, table reservation
8
- Stable tag: 1.2.3
9
  License: GPLv2 or later
10
  Donate link: http://themeofthecrop.com
11
 
@@ -16,12 +16,13 @@ Accept restaurant reservations and table bookings online. Quickly confirm or rej
16
  Accept restaurant reservations and table bookings online. Quickly confirm or reject bookings, send out custom email notifications, restrict booking times and more.
17
 
18
  * Quickly confirm or reject a booking
19
- * Admin email notification when a booking request is made
20
- * Customer email notifications when their request is confirmed or rejected
21
- * Limit available booking times
22
  * Custom user role to manage bookings
23
  * Add your booking form to any page, post or widget area
24
  * Customize all notification messages, and date and time formats
 
25
 
26
  More features will be added to this plugin and addons will be created which extend the functionality or integrate with third-party services. Follow future developments at [Theme of the Crop](http://themeofthecrop.com/?utm_source=Plugin&utm_medium=Plugin%20Description&utm_campaign=Restaurant%20Reservations) or read the Upgrade Notices when you see updates for this plugin in your WordPress admin panel.
27
 
@@ -29,7 +30,7 @@ This plugin is part of a group of plugins for restaurants. Check out the [Food a
29
 
30
  = How to use =
31
 
32
- There is a short guide to using the plugin in the /docs/ folder. It can be accessed by following the Help link listed under the plugin on the Plugins page in your WordPress admin area. Not sure where that is? One of the [screenshots](http://wordpress.org/plugins/restaurant-reservations/screenshots/) for this plugin will show you where to find it.
33
 
34
  = Addons =
35
  [MailChimp for Restaurant Reservations](http://themeofthecrop.com/plugin/mailchimp-restaurant-reservations/?utm_source=Plugin&utm_medium=Plugin%20Description&utm_campaign=Restaurant%20Reservations) - Subscribe emails from new restaurant reservations to your MailChimp mailing list.
@@ -87,10 +88,27 @@ If you make a translation, please help others out by adding it to the [GitHub re
87
  6. Customize the admin notification email when a new booking request is made. Add a quick link to confirm or reject a request straight from the email.
88
  7. Customize the notification email sent to a user when they make a new booking request.
89
  8. Customize the notification email sent to a user when their booking is confirmed. You can also customize the email sent when a booking is rejected.
90
- 9. Access a short guide from your Plugins list to help you get started quickly.
 
91
 
92
  == Changelog ==
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  = 1.2.3 (2014-11-04) =
95
  * Add a {user_email} notification template tag
96
  * Add filter to notification template tag descriptions for extensions
@@ -150,11 +168,14 @@ If you make a translation, please help others out by adding it to the [GitHub re
150
 
151
  == Upgrade Notice ==
152
 
 
 
 
153
  = 1.2.3 =
154
  This update adds a {user_email} notification template tag and improves the mail headers on notifications to mitigate spam risk. It also adds the missing translation for the Clear button in the time picker for many languages. More minor bug fixes listed in the changelog.
155
 
156
  = 1.2.2 =
157
- This update adds support for a new MailChimp addon that will be released soon. An addons page is now available under the Bookings menu. A bug in which custom date/time formats could cause validation errors has been fixed. New hooks are now in place so that it's easier to customize the form output.
158
 
159
  = 1.2.1 =
160
  This is a minor maintenance update which fixes a couple of small bugs.
5
  Requires at Least: 3.8
6
  Tested Up To: 4.1
7
  Tags: restaurant, reservations, bookings, table bookings, restaurant reservation, table reservation
8
+ Stable tag: 1.3
9
  License: GPLv2 or later
10
  Donate link: http://themeofthecrop.com
11
 
16
  Accept restaurant reservations and table bookings online. Quickly confirm or reject bookings, send out custom email notifications, restrict booking times and more.
17
 
18
  * Quickly confirm or reject a booking
19
+ * Receive an email notification when a booking request is made
20
+ * Notify a customer by email when their request is confirmed or rejected
21
+ * Automatically block bookings when you're closed, including holidays and one-off openings
22
  * Custom user role to manage bookings
23
  * Add your booking form to any page, post or widget area
24
  * Customize all notification messages, and date and time formats
25
+ * Add and edit bookings from the admin panel
26
 
27
  More features will be added to this plugin and addons will be created which extend the functionality or integrate with third-party services. Follow future developments at [Theme of the Crop](http://themeofthecrop.com/?utm_source=Plugin&utm_medium=Plugin%20Description&utm_campaign=Restaurant%20Reservations) or read the Upgrade Notices when you see updates for this plugin in your WordPress admin panel.
28
 
30
 
31
  = How to use =
32
 
33
+ There is a short guide to using the plugin in the /docs/ folder. It can be accessed by following the Help link listed under the plugin on the Plugins page in your WordPress admin area. Not sure where that is? The last [screenshot](http://wordpress.org/plugins/restaurant-reservations/screenshots/) for this plugin will show you where to find it.
34
 
35
  = Addons =
36
  [MailChimp for Restaurant Reservations](http://themeofthecrop.com/plugin/mailchimp-restaurant-reservations/?utm_source=Plugin&utm_medium=Plugin%20Description&utm_campaign=Restaurant%20Reservations) - Subscribe emails from new restaurant reservations to your MailChimp mailing list.
88
  6. Customize the admin notification email when a new booking request is made. Add a quick link to confirm or reject a request straight from the email.
89
  7. Customize the notification email sent to a user when they make a new booking request.
90
  8. Customize the notification email sent to a user when their booking is confirmed. You can also customize the email sent when a booking is rejected.
91
+ 9. Add and edit bookings from an admin panel.
92
+ 10. Access a short guide from your Plugins list to help you get started quickly.
93
 
94
  == Changelog ==
95
 
96
+ = 1.3 (2015-02-03) =
97
+ * Add and edit bookings from the admin area
98
+ * Fix: date and time pickers broken on iOS 8 devices
99
+ * Add complete German translation from scolast34
100
+ * Add partial Dutch and Chilean translations
101
+ * Change Party text field to a dropdown selection
102
+ * Bookings admin panel shows upcoming bookings by default
103
+ * Use new HTML5 input types for email and phone
104
+ * Change textdomain to comply with upcoming translation standards
105
+ * Improve WPML compatibility
106
+ * New support for assigning custom classes to fields, fieldsets and legends. h/t Primoz Cigler
107
+ * New filters for email notifications
108
+ * Fix: some bookings menu pages don't load when screen names are translated
109
+ * Fix: addons list won't load if allow_url_fopen is disabled
110
+
111
+
112
  = 1.2.3 (2014-11-04) =
113
  * Add a {user_email} notification template tag
114
  * Add filter to notification template tag descriptions for extensions
168
 
169
  == Upgrade Notice ==
170
 
171
+ = 1.3 =
172
+ This update adds support for adding and editing bookings from the admin panel. The bookings panel now shows upcoming bookings by default. The Party field in the booking form is now a dropdown selection. Plus a bunch of new features and fixes. Read the full changelog for details.
173
+
174
  = 1.2.3 =
175
  This update adds a {user_email} notification template tag and improves the mail headers on notifications to mitigate spam risk. It also adds the missing translation for the Clear button in the time picker for many languages. More minor bug fixes listed in the changelog.
176
 
177
  = 1.2.2 =
178
+ This update adds support for a new MailChimp addon that will be released soon. An addons page is now available under the Bookings menu. A bug in which custom date/time formats could cause validation errors has been fixed. New hooks are now in place so that it's easier to customize the form output.
179
 
180
  = 1.2.1 =
181
  This is a minor maintenance update which fixes a couple of small bugs.
restaurant-reservations.php CHANGED
@@ -3,15 +3,13 @@
3
  * Plugin Name: Restaurant Reservations
4
  * Plugin URI: http://themeofthecrop.com
5
  * Description: Accept restaurant reservations and bookings online.
6
- * Version: 1.2.3
7
  * Author: Theme of the Crop
8
  * Author URI: http://themeofthecrop.com
9
  * License: GNU General Public License v2.0 or later
10
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
- * Requires at least: 3.8
12
- * Tested up to: 4.1
13
  *
14
- * Text Domain: rtbdomain
15
  * Domain Path: /languages/
16
  *
17
  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
@@ -37,13 +35,18 @@ class rtbInit {
37
  */
38
  public $form_rendered = false;
39
 
 
 
 
 
 
 
40
  /**
41
  * Initialize the plugin and register hooks
42
  */
43
  public function __construct() {
44
 
45
  // Common strings
46
- define( 'RTB_TEXTDOMAIN', 'rtbdomain' );
47
  define( 'RTB_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
48
  define( 'RTB_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
49
  define( 'RTB_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
@@ -51,10 +54,14 @@ class rtbInit {
51
  define( 'RTB_BOOKING_POST_TYPE_SLUG', 'booking' );
52
  define( 'RTB_LOAD_FRONTEND_ASSETS', apply_filters( 'rtb-load-frontend-assets', true ) );
53
 
54
-
55
  // Initialize the plugin
56
  add_action( 'init', array( $this, 'load_textdomain' ) );
57
 
 
 
 
 
 
58
  // Add custom roles and capabilities
59
  add_action( 'init', array( $this, 'add_roles' ) );
60
 
@@ -62,15 +69,16 @@ class rtbInit {
62
  require_once( RTB_PLUGIN_DIR . '/includes/CustomPostTypes.class.php' );
63
  $this->cpts = new rtbCustomPostTypes();
64
 
65
- // Add the admin menu
66
- add_action( 'admin_menu', array( $this, 'add_menu_page' ) );
67
-
68
  // Flush the rewrite rules for the custom post types
69
  register_activation_hook( __FILE__, array( $this, 'rewrite_flush' ) );
70
 
71
  // Load the template functions which print the booking form, etc
72
  require_once( RTB_PLUGIN_DIR . '/includes/template-functions.php' );
73
 
 
 
 
 
74
  // Load assets
75
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
76
  add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ) );
@@ -101,6 +109,10 @@ class rtbInit {
101
  )
102
  );
103
 
 
 
 
 
104
  }
105
 
106
  /**
@@ -118,7 +130,7 @@ class rtbInit {
118
  * @since 0.0.1
119
  */
120
  public function load_textdomain() {
121
- load_plugin_textdomain( RTB_TEXTDOMAIN, false, plugin_basename( dirname( __FILE__ ) ) . "/languages/" );
122
  }
123
 
124
  /**
@@ -133,7 +145,7 @@ class rtbInit {
133
  // in the account.
134
  $booking_manager = add_role(
135
  'rtb_booking_manager',
136
- __( 'Booking Manager', RTB_TEXTDOMAIN ),
137
  array(
138
  'read' => true,
139
  'manage_bookings' => true,
@@ -154,52 +166,6 @@ class rtbInit {
154
  }
155
  }
156
 
157
- /**
158
- * Add the top-level admin menu page
159
- * @since 0.0.1
160
- */
161
- public function add_menu_page() {
162
-
163
- add_menu_page(
164
- _x( 'Bookings', 'Title of admin page that lists bookings', RTB_TEXTDOMAIN ),
165
- _x( 'Bookings', 'Title of bookings admin menu item', RTB_TEXTDOMAIN ),
166
- 'manage_bookings',
167
- 'rtb-bookings',
168
- array( $this, 'show_admin_bookings_page' ),
169
- 'dashicons-calendar',
170
- '26.2987'
171
- );
172
-
173
- }
174
-
175
- /**
176
- * Display the admin bookings page
177
- * @since 0.0.1
178
- */
179
- public function show_admin_bookings_page() {
180
-
181
- require_once( RTB_PLUGIN_DIR . '/includes/WP_List_Table.BookingsTable.class.php' );
182
- $bookings_table = new rtbBookingsTable();
183
- $bookings_table->prepare_items();
184
- ?>
185
-
186
- <div class="wrap">
187
- <h2><?php _e( 'Restaurant Bookings', RTB_TEXTDOMAIN ); ?></h2>
188
- <?php do_action( 'rtb_bookings_table_top' ); ?>
189
- <form id="rtb-bookings-table" method="POST" action="">
190
- <input type="hidden" name="post_type" value="<?php echo RTB_BOOKING_POST_TYPE; ?>" />
191
- <input type="hidden" name="page" value="rtb-bookings">
192
-
193
- <?php $bookings_table->views(); ?>
194
- <?php $bookings_table->advanced_filters(); ?>
195
- <?php $bookings_table->display(); ?>
196
- </form>
197
- <?php do_action( 'rtb_bookings_table_btm' ); ?>
198
- </div>
199
-
200
- <?php
201
- }
202
-
203
  /**
204
  * Append booking form to a post's $content variable
205
  * @since 0.0.1
@@ -216,7 +182,7 @@ class rtbInit {
216
  }
217
 
218
  global $post;
219
- if ( $post->ID !== $this->settings->get_setting( 'booking-page' ) ) {
220
  return $content;
221
  }
222
 
@@ -229,10 +195,37 @@ class rtbInit {
229
  */
230
  public function enqueue_admin_assets() {
231
 
 
 
 
 
 
232
  $screen = get_current_screen();
233
- if ( $screen->base == 'toplevel_page_rtb-bookings' || $screen->base == 'bookings_page_rtb-settings' || $screen->base == 'bookings_page_rtb-addons' ) {
 
 
 
 
234
  wp_enqueue_style( 'rtb-admin', RTB_PLUGIN_URL . '/assets/css/admin.css' );
235
  wp_enqueue_script( 'rtb-admin', RTB_PLUGIN_URL . '/assets/js/admin.js', array( 'jquery' ), '', true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  }
237
  }
238
 
@@ -285,7 +278,7 @@ class rtbInit {
285
 
286
  if ( $plugin == RTB_PLUGIN_FNAME ) {
287
 
288
- $links['help'] = '<a href="' . RTB_PLUGIN_URL . '/docs" title="' . __( 'View the help documentation for Restaurant Reservations', RTB_TEXTDOMAIN ) . '">' . __( 'Help', RTB_TEXTDOMAIN ) . '</a>';
289
  }
290
 
291
  return $links;
3
  * Plugin Name: Restaurant Reservations
4
  * Plugin URI: http://themeofthecrop.com
5
  * Description: Accept restaurant reservations and bookings online.
6
+ * Version: 1.3
7
  * Author: Theme of the Crop
8
  * Author URI: http://themeofthecrop.com
9
  * License: GNU General Public License v2.0 or later
10
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
 
 
11
  *
12
+ * Text Domain: restaurant-reservations
13
  * Domain Path: /languages/
14
  *
15
  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
35
  */
36
  public $form_rendered = false;
37
 
38
+ /**
39
+ * An object which stores a booking request, or an empty object if
40
+ * no request has been processed.
41
+ */
42
+ public $request;
43
+
44
  /**
45
  * Initialize the plugin and register hooks
46
  */
47
  public function __construct() {
48
 
49
  // Common strings
 
50
  define( 'RTB_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
51
  define( 'RTB_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
52
  define( 'RTB_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
54
  define( 'RTB_BOOKING_POST_TYPE_SLUG', 'booking' );
55
  define( 'RTB_LOAD_FRONTEND_ASSETS', apply_filters( 'rtb-load-frontend-assets', true ) );
56
 
 
57
  // Initialize the plugin
58
  add_action( 'init', array( $this, 'load_textdomain' ) );
59
 
60
+ // Set up empty request object
61
+ $this->request = new stdClass();
62
+ $this->request->request_processed = false;
63
+ $this->request->request_inserted = false;
64
+
65
  // Add custom roles and capabilities
66
  add_action( 'init', array( $this, 'add_roles' ) );
67
 
69
  require_once( RTB_PLUGIN_DIR . '/includes/CustomPostTypes.class.php' );
70
  $this->cpts = new rtbCustomPostTypes();
71
 
 
 
 
72
  // Flush the rewrite rules for the custom post types
73
  register_activation_hook( __FILE__, array( $this, 'rewrite_flush' ) );
74
 
75
  // Load the template functions which print the booking form, etc
76
  require_once( RTB_PLUGIN_DIR . '/includes/template-functions.php' );
77
 
78
+ // Load the admin bookings page
79
+ require_once( RTB_PLUGIN_DIR . '/includes/AdminBookings.class.php' );
80
+ new rtbAdminBookings();
81
+
82
  // Load assets
83
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
84
  add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ) );
109
  )
110
  );
111
 
112
+ // Load backwards compatibility functions
113
+ require_once( RTB_PLUGIN_DIR . '/includes/Compatibility.class.php' );
114
+ new rtbCompatibility();
115
+
116
  }
117
 
118
  /**
130
  * @since 0.0.1
131
  */
132
  public function load_textdomain() {
133
+ load_plugin_textdomain( 'restaurant-reservations', false, plugin_basename( dirname( __FILE__ ) ) . "/languages/" );
134
  }
135
 
136
  /**
145
  // in the account.
146
  $booking_manager = add_role(
147
  'rtb_booking_manager',
148
+ __( 'Booking Manager', 'restaurant-reservations' ),
149
  array(
150
  'read' => true,
151
  'manage_bookings' => true,
166
  }
167
  }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  /**
170
  * Append booking form to a post's $content variable
171
  * @since 0.0.1
182
  }
183
 
184
  global $post;
185
+ if ( $post->ID != $this->settings->get_setting( 'booking-page' ) ) {
186
  return $content;
187
  }
188
 
195
  */
196
  public function enqueue_admin_assets() {
197
 
198
+ // Use the page reference in $admin_page_hooks because
199
+ // it changes in SOME hooks when it is translated.
200
+ // https://core.trac.wordpress.org/ticket/18857
201
+ global $admin_page_hooks;
202
+
203
  $screen = get_current_screen();
204
+ if ( empty( $screen ) || empty( $admin_page_hooks['rtb-bookings'] ) ) {
205
+ return;
206
+ }
207
+
208
+ if ( $screen->base == 'toplevel_page_rtb-bookings' || $screen->base == $admin_page_hooks['rtb-bookings'] . '_page_rtb-settings' || $screen->base == $admin_page_hooks['rtb-bookings'] . '_page_rtb-addons' ) {
209
  wp_enqueue_style( 'rtb-admin', RTB_PLUGIN_URL . '/assets/css/admin.css' );
210
  wp_enqueue_script( 'rtb-admin', RTB_PLUGIN_URL . '/assets/js/admin.js', array( 'jquery' ), '', true );
211
+ wp_localize_script(
212
+ 'rtb-admin',
213
+ 'rtb_admin',
214
+ array(
215
+ 'nonce' => wp_create_nonce( 'rtb-admin' ),
216
+ 'strings' => array(
217
+ 'add_booking' => __( 'Add Booking', 'restaurant-reservations' ),
218
+ 'edit_booking' => __( 'Edit Booking', 'restaurant-reservations' ),
219
+ 'error_unspecified' => __( 'An unspecified error occurred. Please try again. If the problem persists, try logging out and logging back in.', 'restaurant-reservations' ),
220
+ ),
221
+ )
222
+ );
223
+ }
224
+
225
+ // Enqueue frontend assets to add/edit bookins on the bookings page
226
+ if ( $screen->base == 'toplevel_page_rtb-bookings' ) {
227
+ $this->register_assets();
228
+ rtb_enqueue_assets();
229
  }
230
  }
231
 
278
 
279
  if ( $plugin == RTB_PLUGIN_FNAME ) {
280
 
281
+ $links['help'] = '<a href="' . RTB_PLUGIN_URL . '/docs" title="' . __( 'View the help documentation for Restaurant Reservations', 'restaurant-reservations' ) . '">' . __( 'Help', 'restaurant-reservations' ) . '</a>';
282
  }
283
 
284
  return $links;
screenshot-10.png ADDED
Binary file
screenshot-9.png CHANGED
Binary file