Version Description
Download this release
Release Info
Developer | NateWr |
Plugin | ![]() |
Version | 1.7 |
Comparing to | |
See all releases |
Code changes from version 1.6.3 to 1.7
- Gruntfile.js +30 -15
- assets/addons-backup.json +0 -29
- assets/css/admin.css +53 -42
- assets/img/custom-fields.png +0 -0
- assets/img/export-bookings.png +0 -0
- assets/img/mailchimp.png +0 -0
- assets/img/themes.png +0 -0
- assets/js/admin.js +136 -113
- assets/js/booking-form.js +56 -10
- includes/Addons.class.php +82 -161
- includes/AdminBookings.class.php +86 -0
- includes/Booking.class.php +96 -2
- includes/Compatibility.class.php +2 -1
- includes/MultipleLocations.class.php +0 -27
- includes/Notifications.class.php +2 -0
- includes/Settings.class.php +57 -17
- includes/WP_List_Table.BookingsTable.class.php +41 -21
- includes/integrations/business-profile.php +1 -1
- includes/template-functions.php +31 -20
- languages/restaurant-reservations.pot +344 -308
- package.json +3 -2
- readme.txt → readme.md +110 -87
- restaurant-reservations.php +8 -10
Gruntfile.js
CHANGED
@@ -5,6 +5,8 @@ module.exports = function(grunt) {
|
|
5 |
// Project configuration.
|
6 |
grunt.initConfig({
|
7 |
|
|
|
|
|
8 |
// Configure JSHint
|
9 |
jshint: {
|
10 |
test: {
|
@@ -24,33 +26,46 @@ module.exports = function(grunt) {
|
|
24 |
makepot: {
|
25 |
target: {
|
26 |
options: {
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
mainFile: 'restaurant-reservations/restaurant-reservations.php', // Main project file.
|
33 |
-
potComments: '', // The copyright at the beginning of the POT file.
|
34 |
-
potFilename: '', // Name of the POT file.
|
35 |
-
potHeaders: {
|
36 |
-
poedit: true, // Includes common Poedit headers.
|
37 |
-
'x-poedit-keywordslist': true // Include a list of all possible gettext functions.
|
38 |
-
}, // Headers to add to the generated POT file.
|
39 |
-
processPot: null, // A callback function for manipulating the POT file.
|
40 |
-
type: 'wp-plugin', // Type of project (wp-plugin or wp-theme).
|
41 |
-
updateTimestamp: true // Whether the POT-Creation-Date should be updated without other changes.
|
42 |
}
|
43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
}
|
45 |
|
46 |
});
|
47 |
|
48 |
// Load tasks
|
|
|
49 |
grunt.loadNpmTasks('grunt-contrib-jshint');
|
50 |
grunt.loadNpmTasks('grunt-contrib-watch');
|
51 |
grunt.loadNpmTasks('grunt-wp-i18n');
|
52 |
|
53 |
// Default task(s).
|
54 |
grunt.registerTask('default', ['watch']);
|
|
|
|
|
55 |
|
56 |
};
|
5 |
// Project configuration.
|
6 |
grunt.initConfig({
|
7 |
|
8 |
+
pkg: grunt.file.readJSON('package.json'),
|
9 |
+
|
10 |
// Configure JSHint
|
11 |
jshint: {
|
12 |
test: {
|
26 |
makepot: {
|
27 |
target: {
|
28 |
options: {
|
29 |
+
processPot: function( pot, options ) {
|
30 |
+
pot.headers['report-msgid-bugs-to'] = 'https://themeofthecrop.com';
|
31 |
+
return pot;
|
32 |
+
},
|
33 |
+
type: 'wp-plugin',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
}
|
36 |
+
},
|
37 |
+
|
38 |
+
// Build a package for distribution
|
39 |
+
compress: {
|
40 |
+
main: {
|
41 |
+
options: {
|
42 |
+
archive: 'restaurant-reservations-<%= pkg.version %>.zip'
|
43 |
+
},
|
44 |
+
files: [
|
45 |
+
{
|
46 |
+
src: [
|
47 |
+
'*', '**/*',
|
48 |
+
'!restaurant-reservations-<%= pkg.version %>.zip',
|
49 |
+
'!.*', '!Gruntfile.js', '!package.json', '!node_modules', '!node_modules/**/*',
|
50 |
+
'!**/.*', '!**/Gruntfile.js', '!**/package.json', '!**/node_modules', '!**/node_modules/**/*',
|
51 |
+
],
|
52 |
+
dest: 'restaurant-reservations/',
|
53 |
+
}
|
54 |
+
]
|
55 |
+
}
|
56 |
}
|
57 |
|
58 |
});
|
59 |
|
60 |
// Load tasks
|
61 |
+
grunt.loadNpmTasks('grunt-contrib-compress');
|
62 |
grunt.loadNpmTasks('grunt-contrib-jshint');
|
63 |
grunt.loadNpmTasks('grunt-contrib-watch');
|
64 |
grunt.loadNpmTasks('grunt-wp-i18n');
|
65 |
|
66 |
// Default task(s).
|
67 |
grunt.registerTask('default', ['watch']);
|
68 |
+
grunt.registerTask('build', ['jshint']);
|
69 |
+
grunt.registerTask('package', ['build', 'compress']);
|
70 |
|
71 |
};
|
assets/addons-backup.json
DELETED
@@ -1,29 +0,0 @@
|
|
1 |
-
[
|
2 |
-
{
|
3 |
-
"id":"custom-fields-for-rtb",
|
4 |
-
"title":"Custom Fields for Restaurant Reservations",
|
5 |
-
"url":"http:\/\/themeofthecrop.com\/plugin\/custom-fields-restaurant-reservations\/",
|
6 |
-
"price":"$30",
|
7 |
-
"img":"https:\/\/themeofthecrop.com\/promo\/plugins\/custom-fields-for-rtb.png",
|
8 |
-
"status":"released",
|
9 |
-
"description":"Add custom fields and edit your booking form with ease."
|
10 |
-
},
|
11 |
-
{
|
12 |
-
"id":"mailchimp-for-rtb",
|
13 |
-
"title":"MailChimp for Restaurant Reservations",
|
14 |
-
"url":"http:\/\/themeofthecrop.com\/plugin\/mailchimp-restaurant-reservations\/",
|
15 |
-
"price":"$20",
|
16 |
-
"img":"https:\/\/themeofthecrop.com\/promo\/plugins\/mailchimp-for-rtb.png",
|
17 |
-
"status":"released",
|
18 |
-
"description":"Subscribe emails from new restaurant reservations to your MailChimp mailing list. <strong>Use a different mailing list provider? Let me know <a href=\"http:\/\/themeofthecrop.com\/2015\/12\/17\/suggest-next-mailing-list-integration\/?utm_source=Plugin&utm_medium=Addon%20List&utm_campaign=Restaurant%20Reservations\">which one</a>.</strong>"
|
19 |
-
},
|
20 |
-
{
|
21 |
-
"id":"export-bookings-for-rtb",
|
22 |
-
"title":"Export Bookings for Restaurant Reservations",
|
23 |
-
"url":"http:\/\/themeofthecrop.com\/plugin\/export-bookings-for-restaurant-reservations\/",
|
24 |
-
"price":"$20",
|
25 |
-
"img":"https:\/\/themeofthecrop.com\/promo\/plugins\/export-bookings-for-rtb.png",
|
26 |
-
"status":"released",
|
27 |
-
"description":"Export your restaurant reservations to PDF and Excel/CSV files."
|
28 |
-
}
|
29 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/css/admin.css
CHANGED
@@ -355,7 +355,7 @@
|
|
355 |
width: 100%;
|
356 |
height: 100%;
|
357 |
background: rgba(0, 0, 0, 0.8);
|
358 |
-
z-index:
|
359 |
overflow-y: auto;
|
360 |
cursor: pointer;
|
361 |
visibility: hidden;
|
@@ -445,6 +445,12 @@
|
|
445 |
-webkit-transition: opacity .25s ease-in-out;
|
446 |
}
|
447 |
|
|
|
|
|
|
|
|
|
|
|
|
|
448 |
.rtb-admin-modal .action-status {
|
449 |
display: inline-block;
|
450 |
float: right;
|
@@ -541,6 +547,23 @@
|
|
541 |
#rtb-error-modal .rtb-error-msg {
|
542 |
margin-bottom: 1em;
|
543 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
544 |
/* Hide the outer scrollbar when the modal is open */
|
545 |
.rtb-hide-body-scroll {
|
546 |
overflow: hidden !important;
|
@@ -561,60 +584,35 @@
|
|
561 |
}
|
562 |
|
563 |
/* Addons Page */
|
564 |
-
|
565 |
margin-top: 2em;
|
566 |
}
|
567 |
|
568 |
-
|
569 |
-
line-height: 10em;
|
570 |
-
font-size: 2em;
|
571 |
-
text-align: center;
|
572 |
-
text-transform: uppercase;
|
573 |
-
font-weight: bold;
|
574 |
-
background: #eee;
|
575 |
-
background: rgba(0,0,0,0.1);
|
576 |
-
color: #777;
|
577 |
-
color: rgba(0,0,0,0.54);
|
578 |
-
}
|
579 |
-
|
580 |
-
#rtb-addons .rtb-loading .spinner {
|
581 |
-
float: none;
|
582 |
-
visibility: visible;
|
583 |
display: inline-block;
|
584 |
-
}
|
585 |
-
|
586 |
-
#rtb-addons .error {
|
587 |
-
padding: 0.25em 0.5em;
|
588 |
-
background: #f50;
|
589 |
-
color: #fff;
|
590 |
-
}
|
591 |
-
|
592 |
-
#rtb-addons .error a {
|
593 |
-
color: #fff;
|
594 |
-
}
|
595 |
-
|
596 |
-
#rtb-addons .addon {
|
597 |
margin-bottom: 20px;
|
598 |
padding: 20px;
|
599 |
background: #fff;
|
600 |
-
min-height:
|
601 |
border-radius: 3px;
|
602 |
-
|
|
|
|
|
603 |
}
|
604 |
|
605 |
-
|
606 |
float: left;
|
607 |
-
width:
|
608 |
-
height:
|
609 |
margin: 0 20px 20px 0;
|
610 |
}
|
611 |
|
612 |
-
|
613 |
margin-top: 2em;
|
614 |
}
|
615 |
|
616 |
-
|
617 |
-
|
618 |
line-height: 28px;
|
619 |
display: inline-block;
|
620 |
padding: 0 0.75em;
|
@@ -622,26 +620,39 @@
|
|
622 |
box-shadow: 0 1px 0 #ccc;
|
623 |
}
|
624 |
|
625 |
-
|
626 |
background: #F0F05E;
|
627 |
}
|
628 |
|
629 |
-
|
630 |
background: #81F05E;
|
631 |
}
|
632 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
633 |
@media screen and (max-width: 600px) {
|
634 |
|
635 |
-
|
636 |
text-align: center;
|
637 |
}
|
638 |
|
639 |
-
|
640 |
float: none;
|
641 |
margin: 0;
|
642 |
}
|
643 |
}
|
644 |
|
|
|
645 |
/* License page */
|
646 |
.rtb-license-setting .status {
|
647 |
display: inline-block;
|
355 |
width: 100%;
|
356 |
height: 100%;
|
357 |
background: rgba(0, 0, 0, 0.8);
|
358 |
+
z-index: 9999;
|
359 |
overflow-y: auto;
|
360 |
cursor: pointer;
|
361 |
visibility: hidden;
|
445 |
-webkit-transition: opacity .25s ease-in-out;
|
446 |
}
|
447 |
|
448 |
+
.rtb-admin-modal .button-link {
|
449 |
+
display: inline-block;
|
450 |
+
margin-top: 1em;
|
451 |
+
line-height: 26px;
|
452 |
+
}
|
453 |
+
|
454 |
.rtb-admin-modal .action-status {
|
455 |
display: inline-block;
|
456 |
float: right;
|
547 |
#rtb-error-modal .rtb-error-msg {
|
548 |
margin-bottom: 1em;
|
549 |
}
|
550 |
+
|
551 |
+
.rtb-ban-form .intro {
|
552 |
+
margin-top: 0;
|
553 |
+
font-weight: bold;
|
554 |
+
}
|
555 |
+
|
556 |
+
.rtb-ban-form .intro span {
|
557 |
+
color: #a55;
|
558 |
+
}
|
559 |
+
|
560 |
+
.rtb-ban-form .button-primary {
|
561 |
+
display: block;
|
562 |
+
width: 100%;
|
563 |
+
margin-top: 2em;
|
564 |
+
margin-bottom: 2em;
|
565 |
+
}
|
566 |
+
|
567 |
/* Hide the outer scrollbar when the modal is open */
|
568 |
.rtb-hide-body-scroll {
|
569 |
overflow: hidden !important;
|
584 |
}
|
585 |
|
586 |
/* Addons Page */
|
587 |
+
.rtb-addons {
|
588 |
margin-top: 2em;
|
589 |
}
|
590 |
|
591 |
+
.rtb-addons .addon {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
592 |
display: inline-block;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
593 |
margin-bottom: 20px;
|
594 |
padding: 20px;
|
595 |
background: #fff;
|
596 |
+
min-height: 150px;
|
597 |
border-radius: 3px;
|
598 |
+
max-width: 40em;
|
599 |
+
margin-right: 20px;
|
600 |
+
vertical-align: top;
|
601 |
}
|
602 |
|
603 |
+
.rtb-addons img {
|
604 |
float: left;
|
605 |
+
width: 150px;
|
606 |
+
height: 150px;
|
607 |
margin: 0 20px 20px 0;
|
608 |
}
|
609 |
|
610 |
+
.rtb-addons .action {
|
611 |
margin-top: 2em;
|
612 |
}
|
613 |
|
614 |
+
.rtb-addons .soon,
|
615 |
+
.rtb-addons .installed {
|
616 |
line-height: 28px;
|
617 |
display: inline-block;
|
618 |
padding: 0 0.75em;
|
620 |
box-shadow: 0 1px 0 #ccc;
|
621 |
}
|
622 |
|
623 |
+
.rtb-addons .soon {
|
624 |
background: #F0F05E;
|
625 |
}
|
626 |
|
627 |
+
.rtb-addons .installed {
|
628 |
background: #81F05E;
|
629 |
}
|
630 |
|
631 |
+
.rtb-addons .addon-themes .action .button {
|
632 |
+
background: #D24C2B;
|
633 |
+
color: #fff;
|
634 |
+
border-color: #a53216;
|
635 |
+
box-shadow: 0 1px 0 #cc3712;
|
636 |
+
}
|
637 |
+
|
638 |
+
.rtb-addons .addon-themes .action .button:hover,
|
639 |
+
.rtb-addons .addon-themes .action .button:focus {
|
640 |
+
background: #ff5126;
|
641 |
+
}
|
642 |
+
|
643 |
@media screen and (max-width: 600px) {
|
644 |
|
645 |
+
.rtb-addons .addon {
|
646 |
text-align: center;
|
647 |
}
|
648 |
|
649 |
+
.rtb-addons img {
|
650 |
float: none;
|
651 |
margin: 0;
|
652 |
}
|
653 |
}
|
654 |
|
655 |
+
|
656 |
/* License page */
|
657 |
.rtb-license-setting .status {
|
658 |
display: inline-block;
|
assets/img/custom-fields.png
ADDED
Binary file
|
assets/img/export-bookings.png
ADDED
Binary file
|
assets/img/mailchimp.png
ADDED
Binary file
|
assets/img/themes.png
ADDED
Binary file
|
assets/js/admin.js
CHANGED
@@ -16,7 +16,7 @@ jQuery(document).ready(function ($) {
|
|
16 |
hiddenName: true,
|
17 |
|
18 |
onStart: function() {
|
19 |
-
if ( input.val()
|
20 |
var date = new Date( input.val() );
|
21 |
if ( Object.prototype.toString.call( date ) === "[object Date]" ) {
|
22 |
this.set( 'select', date );
|
@@ -56,6 +56,9 @@ jQuery(document).ready(function ($) {
|
|
56 |
|
57 |
} else if ( target.data( 'action' ) == 'email') {
|
58 |
rtb_toggle_email_modal( true, target.data( 'id'), target.data( 'email' ), target.data( 'name' ) );
|
|
|
|
|
|
|
59 |
}
|
60 |
|
61 |
e.preventDefault();
|
@@ -87,24 +90,29 @@ jQuery(document).ready(function ($) {
|
|
87 |
/**
|
88 |
* Modals for the admin page
|
89 |
*/
|
90 |
-
var rtb_booking_modal = $( '#rtb-booking-modal'
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
/**
|
110 |
* Show or hide the booking form modal
|
@@ -210,7 +218,11 @@ jQuery(document).ready(function ($) {
|
|
210 |
rtb_details_modal.find( '.actions' ).click( function(e) {
|
211 |
var target = $( e.target );
|
212 |
rtb_toggle_details_modal( false );
|
213 |
-
|
|
|
|
|
|
|
|
|
214 |
});
|
215 |
|
216 |
} else {
|
@@ -222,6 +234,36 @@ jQuery(document).ready(function ($) {
|
|
222 |
}
|
223 |
}
|
224 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
/**
|
226 |
* Initialize form field events
|
227 |
*/
|
@@ -391,6 +433,17 @@ jQuery(document).ready(function ($) {
|
|
391 |
}
|
392 |
});
|
393 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
394 |
// Close modals when ESC is keyed
|
395 |
$(document).keyup( function(e) {
|
396 |
if ( e.which == '27' ) {
|
@@ -399,6 +452,7 @@ jQuery(document).ready(function ($) {
|
|
399 |
rtb_toggle_column_modal( false );
|
400 |
rtb_toggle_details_modal( false );
|
401 |
rtb_toggle_booking_form_error_modal( false );
|
|
|
402 |
}
|
403 |
});
|
404 |
|
@@ -577,119 +631,88 @@ jQuery(document).ready(function ($) {
|
|
577 |
});
|
578 |
});
|
579 |
|
580 |
-
//
|
581 |
-
|
582 |
-
|
583 |
-
var rtbAddons = {
|
584 |
-
|
585 |
-
el: $( '#rtb-addons' ),
|
586 |
-
|
587 |
-
load: function() {
|
588 |
-
|
589 |
-
var params = {
|
590 |
-
action: 'rtb-addons',
|
591 |
-
nonce: rtb_addons.nonce
|
592 |
-
};
|
593 |
-
|
594 |
-
var data = $.param( params );
|
595 |
-
|
596 |
-
// Send Ajax request
|
597 |
-
var jqxhr = $.post( ajaxurl, data, function( r ) {
|
598 |
-
|
599 |
-
rtbAddons.el.find( '.rtb-loading' ).fadeOut( '250', function() {
|
600 |
-
if ( r.success ) {
|
601 |
-
rtbAddons.showAddons( r );
|
602 |
-
} else {
|
603 |
-
rtbAddons.showError( r );
|
604 |
-
}
|
605 |
-
});
|
606 |
-
|
607 |
|
608 |
-
|
609 |
-
|
610 |
|
611 |
-
|
|
|
|
|
612 |
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
|
|
|
|
|
|
|
|
|
|
617 |
|
618 |
-
|
619 |
-
rtbAddons.el.append( rtbAddons.getAddonHTML( r.data[i] ) );
|
620 |
-
rtbAddons.el.find( '.addon.' + r.data[i].id ).fadeIn();
|
621 |
-
}
|
622 |
-
},
|
623 |
|
624 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
625 |
|
626 |
-
|
627 |
-
rtbAddons.el.html( '<span class="error">' + rtb_addons.strings.error_unknown + '</span>' );
|
628 |
-
} else {
|
629 |
-
rtbAddons.el.html( '<span class="error">' + r.data.msg + '</span>' );
|
630 |
-
}
|
631 |
|
632 |
-
|
633 |
|
634 |
-
|
635 |
|
636 |
-
if (
|
637 |
-
|
|
|
|
|
638 |
}
|
639 |
|
640 |
-
|
641 |
-
addon.url += '?utm_source=Plugin&utm_medium=Addon%20List&utm_campaign=Restaurant%20Reservations';
|
642 |
-
|
643 |
-
var html = '<div class="addon ' + addon.id + '">';
|
644 |
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
}
|
650 |
-
|
651 |
-
html += '<h3>' + addon.title + '</h3>';
|
652 |
|
653 |
-
|
654 |
|
655 |
-
if ( typeof
|
656 |
-
|
|
|
|
|
657 |
}
|
658 |
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
html += '<a href="' + addon.url + '" class="button button-primary" target="_blank">';
|
665 |
-
|
666 |
-
if ( typeof addon.price !== 'undefined' && addon.price.length ) {
|
667 |
-
html += rtb_addons.strings.learn_more;
|
668 |
-
} else {
|
669 |
-
html += rtb_addons.strings.free;
|
670 |
-
}
|
671 |
-
|
672 |
-
html += '</a>';
|
673 |
-
|
674 |
-
} else if ( addon.status === 'installed' ) {
|
675 |
-
html += '<span class="installed">' + rtb_addons.strings.installed + '</span>';
|
676 |
-
|
677 |
-
} else {
|
678 |
-
html += '<span class="soon">' + rtb_addons.strings.coming_soon + '</span>';
|
679 |
-
}
|
680 |
-
|
681 |
-
html += '</div>'; // .action
|
682 |
}
|
683 |
|
684 |
-
|
685 |
|
686 |
-
|
687 |
-
|
688 |
-
|
|
|
689 |
}
|
690 |
-
|
691 |
-
|
692 |
-
rtbAddons.load();
|
693 |
}
|
694 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
695 |
});
|
16 |
hiddenName: true,
|
17 |
|
18 |
onStart: function() {
|
19 |
+
if ( input.val() !== '' ) {
|
20 |
var date = new Date( input.val() );
|
21 |
if ( Object.prototype.toString.call( date ) === "[object Date]" ) {
|
22 |
this.set( 'select', date );
|
56 |
|
57 |
} else if ( target.data( 'action' ) == 'email') {
|
58 |
rtb_toggle_email_modal( true, target.data( 'id'), target.data( 'email' ), target.data( 'name' ) );
|
59 |
+
|
60 |
+
} else if ( target.data( 'action' ) == 'ban') {
|
61 |
+
rtb_toggle_ban_modal( true, target.data( 'id'), target.data( 'email' ), target.data( 'ip' ) );
|
62 |
}
|
63 |
|
64 |
e.preventDefault();
|
90 |
/**
|
91 |
* Modals for the admin page
|
92 |
*/
|
93 |
+
var rtb_booking_modal = $( '#rtb-booking-modal' ),
|
94 |
+
rtb_booking_modal_fields = rtb_booking_modal.find( '#rtb-booking-form-fields' ),
|
95 |
+
rtb_booking_modal_submit = rtb_booking_modal.find( 'button' ),
|
96 |
+
rtb_booking_modal_cancel = rtb_booking_modal.find( '#rtb-cancel-booking-modal' ),
|
97 |
+
rtb_booking_modal_action_status = rtb_booking_modal.find( '.action-status' ),
|
98 |
+
rtb_email_modal = $( '#rtb-email-modal' ),
|
99 |
+
rtb_email_modal_submit = rtb_email_modal.find( 'button' ),
|
100 |
+
rtb_email_modal_cancel = rtb_email_modal.find( '#rtb-cancel-email-modal' ),
|
101 |
+
rtb_email_modal_action_status = rtb_email_modal.find( '.action-status' ),
|
102 |
+
rtb_column_modal = $( '#rtb-column-modal' ),
|
103 |
+
rtb_column_modal_submit = rtb_column_modal.find( 'button' ),
|
104 |
+
rtb_column_modal_cancel = rtb_column_modal.find( '#rtb-cancel-column-modal' ),
|
105 |
+
rtb_column_modal_action_status = rtb_column_modal.find( '.action-status' ),
|
106 |
+
rtb_details_modal = $( '#rtb-details-modal' ),
|
107 |
+
rtb_details_modal_close = rtb_details_modal.find( '#rtb-close-details-modal' ),
|
108 |
+
rtb_details_modal_cancel = rtb_details_modal.find( '#rtb-cancel-details-modal' ),
|
109 |
+
rtb_booking_modal_error = $( '#rtb-error-modal' ),
|
110 |
+
rtb_booking_modal_error_msg = rtb_booking_modal_error.find( '.rtb-error-msg' ),
|
111 |
+
rtb_ban_modal = $( '#rtb-ban-modal' ),
|
112 |
+
rtb_ban_modal_submit_email = rtb_ban_modal.find( '#rtb-ban-modal-email-btn' ),
|
113 |
+
rtb_ban_modal_submit_ip = rtb_ban_modal.find( '#rtb-ban-modal-ip-btn' ),
|
114 |
+
rtb_ban_modal_cancel = rtb_ban_modal.find( '#rtb-cancel-ban-modal' ),
|
115 |
+
rtb_ban_modal_action_status = rtb_ban_modal.find( '.action-status' );
|
116 |
|
117 |
/**
|
118 |
* Show or hide the booking form modal
|
218 |
rtb_details_modal.find( '.actions' ).click( function(e) {
|
219 |
var target = $( e.target );
|
220 |
rtb_toggle_details_modal( false );
|
221 |
+
if ( target.data( 'action' ) == 'email') {
|
222 |
+
rtb_toggle_email_modal( true, target.data( 'id'), target.data( 'email' ), target.data( 'name' ) );
|
223 |
+
} else if ( target.data( 'action' ) == 'ban') {
|
224 |
+
rtb_toggle_ban_modal( true, target.data( 'id'), target.data( 'email' ), target.data( 'ip' ) );
|
225 |
+
}
|
226 |
});
|
227 |
|
228 |
} else {
|
234 |
}
|
235 |
}
|
236 |
|
237 |
+
/**
|
238 |
+
* Show or hide the ban ip/email form modal
|
239 |
+
*/
|
240 |
+
function rtb_toggle_ban_modal( show, id, email, ip ) {
|
241 |
+
|
242 |
+
if ( show ) {
|
243 |
+
rtb_ban_modal.scrollTop( 0 ).addClass( 'is-visible' );
|
244 |
+
rtb_ban_modal.find( '#rtb-ban-modal-email' ).text( email );
|
245 |
+
rtb_ban_modal.find( '#rtb-ban-modal-ip' ).text( ip );
|
246 |
+
if ( rtb_admin.banned_emails.indexOf( email ) > -1 ) {
|
247 |
+
rtb_ban_modal_submit_email.prop( 'disabled', true );
|
248 |
+
}
|
249 |
+
if ( rtb_admin.banned_ips.indexOf( ip ) > -1 ) {
|
250 |
+
rtb_ban_modal_submit_ip.prop( 'disabled', true );
|
251 |
+
}
|
252 |
+
|
253 |
+
$( 'body' ).addClass( 'rtb-hide-body-scroll' );
|
254 |
+
|
255 |
+
} else {
|
256 |
+
rtb_ban_modal.removeClass( 'is-visible' );
|
257 |
+
rtb_ban_modal.find( '#rtb-ban-modal-email' ).text( '' );
|
258 |
+
rtb_ban_modal.find( '#rtb-ban-modal-ip' ).text( '' );
|
259 |
+
rtb_ban_modal_submit_email.prop( 'disabled', false );
|
260 |
+
rtb_ban_modal_submit_ip.prop( 'disabled', false );
|
261 |
+
rtb_ban_modal_cancel.prop( 'disabled', false );
|
262 |
+
|
263 |
+
$( 'body' ).removeClass( 'rtb-hide-body-scroll' );
|
264 |
+
}
|
265 |
+
}
|
266 |
+
|
267 |
/**
|
268 |
* Initialize form field events
|
269 |
*/
|
433 |
}
|
434 |
});
|
435 |
|
436 |
+
// Close ban modal when background or cancel button is clicked
|
437 |
+
rtb_ban_modal.click( function(e) {
|
438 |
+
if ( $(e.target).is( rtb_ban_modal ) ) {
|
439 |
+
rtb_toggle_ban_modal( false );
|
440 |
+
}
|
441 |
+
|
442 |
+
if ( $(e.target).is( rtb_ban_modal_cancel ) && rtb_ban_modal_cancel.prop( 'disabled' ) !== true ) {
|
443 |
+
rtb_toggle_ban_modal( false );
|
444 |
+
}
|
445 |
+
});
|
446 |
+
|
447 |
// Close modals when ESC is keyed
|
448 |
$(document).keyup( function(e) {
|
449 |
if ( e.which == '27' ) {
|
452 |
rtb_toggle_column_modal( false );
|
453 |
rtb_toggle_details_modal( false );
|
454 |
rtb_toggle_booking_form_error_modal( false );
|
455 |
+
rtb_toggle_ban_modal( false );
|
456 |
}
|
457 |
});
|
458 |
|
631 |
});
|
632 |
});
|
633 |
|
634 |
+
// Shared function for banning emails and IPs
|
635 |
+
function rtb_ban_modal_submit( e, type ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
636 |
|
637 |
+
e.preventDefault();
|
638 |
+
e.stopPropagation();
|
639 |
|
640 |
+
if ( $(this).prop( 'disabled' ) === true ) {
|
641 |
+
return;
|
642 |
+
}
|
643 |
|
644 |
+
// Loading
|
645 |
+
if ( type === 'email' ) {
|
646 |
+
rtb_ban_modal_submit_email.prop( 'disabled', true );
|
647 |
+
} else if ( type === 'ip' ) {
|
648 |
+
rtb_ban_modal_submit_ip.prop( 'disabled', true );
|
649 |
+
}
|
650 |
+
rtb_ban_modal_cancel.prop( 'disabled', true );
|
651 |
+
rtb_ban_modal_action_status.addClass( 'is-visible' );
|
652 |
+
rtb_show_action_status( rtb_ban_modal_action_status, 'loading' );
|
653 |
|
654 |
+
var params = {};
|
|
|
|
|
|
|
|
|
655 |
|
656 |
+
params.action = 'rtb-admin-ban-modal';
|
657 |
+
params.nonce = rtb_admin.nonce;
|
658 |
+
if ( type === 'email' ) {
|
659 |
+
params.email = rtb_ban_modal.find( '#rtb-ban-modal-email' ).text();
|
660 |
+
} else if ( type === 'ip' ) {
|
661 |
+
params.ip = rtb_ban_modal.find( '#rtb-ban-modal-ip' ).text();
|
662 |
+
}
|
663 |
|
664 |
+
var data = $.param( params );
|
|
|
|
|
|
|
|
|
665 |
|
666 |
+
var jqhxr = $.post( ajaxurl, data, function( r ) {
|
667 |
|
668 |
+
if ( r.success ) {
|
669 |
|
670 |
+
if ( type === 'email' ) {
|
671 |
+
rtb_admin.banned_emails.push( params.email );
|
672 |
+
} else if ( type === 'ip' ) {
|
673 |
+
rtb_admin.banned_ips.push( params.ip );
|
674 |
}
|
675 |
|
676 |
+
rtb_show_action_status( rtb_ban_modal_action_status, r.success );
|
|
|
|
|
|
|
677 |
|
678 |
+
// Hide result status icon after a few seconds
|
679 |
+
setTimeout( function() {
|
680 |
+
rtb_ban_modal.find( '.action-status' ).removeClass( 'is-visible' );
|
681 |
+
}, 1000 );
|
|
|
|
|
|
|
682 |
|
683 |
+
} else {
|
684 |
|
685 |
+
if ( typeof r.data == 'undefined' || typeof r.data.error == 'undefined' ) {
|
686 |
+
rtb_toggle_booking_form_error_modal( true, rtb_admin.strings.error_unspecified );
|
687 |
+
} else {
|
688 |
+
rtb_toggle_booking_form_error_modal( true, r.data.msg );
|
689 |
}
|
690 |
|
691 |
+
rtb_ban_modal_cancel.prop( 'disabled', false );
|
692 |
+
if ( type === 'email' ) {
|
693 |
+
rtb_ban_modal_submit_email.prop( 'disabled', false );
|
694 |
+
} else if ( type === 'ip' ) {
|
695 |
+
rtb_ban_modal_submit_ip.prop( 'disabled', false );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
696 |
}
|
697 |
|
698 |
+
rtb_show_action_status( rtb_ban_modal_action_status, false );
|
699 |
|
700 |
+
// Hide result status icon after a few seconds
|
701 |
+
setTimeout( function() {
|
702 |
+
rtb_ban_modal.find( '.action-status' ).removeClass( 'is-visible' );
|
703 |
+
}, 4000 );
|
704 |
}
|
705 |
+
});
|
|
|
|
|
706 |
}
|
707 |
|
708 |
+
// Submit ban email form modal
|
709 |
+
rtb_ban_modal_submit_email.click( function(e) {
|
710 |
+
rtb_ban_modal_submit( e, 'email' );
|
711 |
+
});
|
712 |
+
|
713 |
+
// Submit ban ip form modal
|
714 |
+
rtb_ban_modal_submit_ip.click( function(e) {
|
715 |
+
rtb_ban_modal_submit( e, 'ip' );
|
716 |
+
});
|
717 |
+
|
718 |
});
|
assets/js/booking-form.js
CHANGED
@@ -40,7 +40,7 @@ jQuery(document).ready(function ($) {
|
|
40 |
format: rtb_pickadate.date_format,
|
41 |
formatSubmit: 'yyyy/mm/dd',
|
42 |
hiddenName: true,
|
43 |
-
min:
|
44 |
container: 'body',
|
45 |
firstDay: rtb_pickadate.first_day,
|
46 |
|
@@ -112,10 +112,14 @@ jQuery(document).ready(function ($) {
|
|
112 |
rtb_booking_form.datepicker.set( 'disable', disable_dates );
|
113 |
}
|
114 |
|
115 |
-
rtb_pickadate.late_bookings
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
|
|
119 |
}
|
120 |
|
121 |
// If no date has been set, select today's date if it's a valid
|
@@ -161,15 +165,16 @@ jQuery(document).ready(function ($) {
|
|
161 |
return;
|
162 |
}
|
163 |
|
164 |
-
selected_date = new Date( rtb_booking_form.datepicker.get( 'select', 'yyyy/mm/dd' )
|
165 |
-
|
166 |
-
|
167 |
-
|
|
|
168 |
|
169 |
// Declaring the first element true inverts the timepicker settings. All
|
170 |
// times subsequently declared are valid. Any time that doesn't fall
|
171 |
// within those declarations is invalid.
|
172 |
-
// See: http://amsul.ca/pickadate.js/time
|
173 |
var valid_times = [ rtb_booking_form.get_outer_time_range() ];
|
174 |
|
175 |
// Check if this date is an exception to the rules
|
@@ -209,6 +214,8 @@ jQuery(document).ready(function ($) {
|
|
209 |
excp_end_time = [ 24, 0 ]; // End of the day
|
210 |
}
|
211 |
|
|
|
|
|
212 |
valid_times.push( { from: excp_start_time, to: excp_end_time, inverted: true } );
|
213 |
}
|
214 |
}
|
@@ -269,6 +276,8 @@ jQuery(document).ready(function ($) {
|
|
269 |
rule_end_time = [ 24, 0 ]; // End of the day
|
270 |
}
|
271 |
|
|
|
|
|
272 |
valid_times.push( { from: rule_start_time, to: rule_end_time, inverted: true } );
|
273 |
|
274 |
}
|
@@ -337,6 +346,43 @@ jQuery(document).ready(function ($) {
|
|
337 |
}
|
338 |
};
|
339 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
340 |
|
341 |
rtb_booking_form.init();
|
342 |
});
|
40 |
format: rtb_pickadate.date_format,
|
41 |
formatSubmit: 'yyyy/mm/dd',
|
42 |
hiddenName: true,
|
43 |
+
min: !rtb_pickadate.allow_past,
|
44 |
container: 'body',
|
45 |
firstDay: rtb_pickadate.first_day,
|
46 |
|
112 |
rtb_booking_form.datepicker.set( 'disable', disable_dates );
|
113 |
}
|
114 |
|
115 |
+
if ( typeof rtb_pickadate.late_bookings === 'string' && rtb_pickadate.late_bookings == 'same_day' ) {
|
116 |
+
rtb_booking_form.datepicker.set( 'min', 1 );
|
117 |
+
} else if ( typeof rtb_pickadate.late_bookings === 'number' && rtb_pickadate.late_bookings % 1 === 0 ) {
|
118 |
+
rtb_pickadate.late_bookings = parseInt( rtb_pickadate.late_bookings, 10 );
|
119 |
+
if ( rtb_pickadate.late_bookings >= 1440 ) {
|
120 |
+
var min = Math.floor( rtb_pickadate.late_bookings / 1440 );
|
121 |
+
rtb_booking_form.datepicker.set( 'min', min );
|
122 |
+
}
|
123 |
}
|
124 |
|
125 |
// If no date has been set, select today's date if it's a valid
|
165 |
return;
|
166 |
}
|
167 |
|
168 |
+
var selected_date = new Date( rtb_booking_form.datepicker.get( 'select', 'yyyy/mm/dd' ) ),
|
169 |
+
selected_date_year = selected_date.getFullYear(),
|
170 |
+
selected_date_month = selected_date.getMonth(),
|
171 |
+
selected_date_date = selected_date.getDate(),
|
172 |
+
current_date = new Date();
|
173 |
|
174 |
// Declaring the first element true inverts the timepicker settings. All
|
175 |
// times subsequently declared are valid. Any time that doesn't fall
|
176 |
// within those declarations is invalid.
|
177 |
+
// See: http://amsul.ca/pickadate.js/time/#disable-times-all
|
178 |
var valid_times = [ rtb_booking_form.get_outer_time_range() ];
|
179 |
|
180 |
// Check if this date is an exception to the rules
|
214 |
excp_end_time = [ 24, 0 ]; // End of the day
|
215 |
}
|
216 |
|
217 |
+
excp_start_time = rtb_booking_form.get_earliest_time( excp_start_time, selected_date, current_date );
|
218 |
+
|
219 |
valid_times.push( { from: excp_start_time, to: excp_end_time, inverted: true } );
|
220 |
}
|
221 |
}
|
276 |
rule_end_time = [ 24, 0 ]; // End of the day
|
277 |
}
|
278 |
|
279 |
+
rule_start_time = rtb_booking_form.get_earliest_time( rule_start_time, selected_date, current_date );
|
280 |
+
|
281 |
valid_times.push( { from: rule_start_time, to: rule_end_time, inverted: true } );
|
282 |
|
283 |
}
|
346 |
}
|
347 |
};
|
348 |
|
349 |
+
/**
|
350 |
+
* Get the earliest valid time
|
351 |
+
*
|
352 |
+
* This checks the valid time for the day and, if a current day, applies
|
353 |
+
* any late booking restrictions. It also ensures that times in the past
|
354 |
+
* are not availabe.
|
355 |
+
*
|
356 |
+
* @param array start_time
|
357 |
+
* @param array selected_date
|
358 |
+
* @param array current_date
|
359 |
+
*/
|
360 |
+
rtb_booking_form.get_earliest_time = function( start_time, selected_date, current_date ) {
|
361 |
+
|
362 |
+
// Only make adjustments for current day selections
|
363 |
+
if ( selected_date.getDate() !== current_date.getDate() ) {
|
364 |
+
return start_time;
|
365 |
+
}
|
366 |
+
|
367 |
+
// Get the number of minutes after midnight to compare
|
368 |
+
var start_minutes = ( start_time[0] * 60 ) + start_time[1],
|
369 |
+
current_minutes = ( current_date.getHours() * 60 ) + current_date.getMinutes(),
|
370 |
+
late_booking_minutes;
|
371 |
+
|
372 |
+
start_minutes = start_minutes > current_minutes ? start_minutes : current_minutes;
|
373 |
+
|
374 |
+
if ( typeof rtb_pickadate.late_bookings === 'number' && rtb_pickadate.late_bookings % 1 === 0 ) {
|
375 |
+
late_booking_minutes = current_minutes + rtb_pickadate.late_bookings;
|
376 |
+
if ( late_booking_minutes > start_minutes ) {
|
377 |
+
start_minutes = late_booking_minutes;
|
378 |
+
}
|
379 |
+
}
|
380 |
+
|
381 |
+
start_time = [ Math.floor( start_minutes / 60 ), start_minutes % 60 ];
|
382 |
+
|
383 |
+
return start_time;
|
384 |
+
};
|
385 |
+
|
386 |
|
387 |
rtb_booking_form.init();
|
388 |
});
|
includes/Addons.class.php
CHANGED
@@ -9,105 +9,13 @@ if ( !class_exists( 'rtbAddons' ) ) {
|
|
9 |
*/
|
10 |
class rtbAddons {
|
11 |
|
12 |
-
|
13 |
-
* API endpoint to retrieve addons list
|
14 |
-
*/
|
15 |
-
public $api_url;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Plugin slug to retrieve addons for
|
19 |
-
*/
|
20 |
-
public $plugin;
|
21 |
-
|
22 |
-
public function __construct( $args ) {
|
23 |
-
|
24 |
-
$this->parse_args( $args );
|
25 |
-
|
26 |
-
if ( $this->check_config() ) {
|
27 |
-
|
28 |
-
// Add the admin menu
|
29 |
-
add_action( 'admin_menu', array( $this, 'add_menu_page' ), 100 );
|
30 |
-
|
31 |
-
// Send addon data to the javascript
|
32 |
-
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
|
33 |
-
|
34 |
-
// Receive ajax calls to fetch addons
|
35 |
-
add_action( 'wp_ajax_nopriv_rtb-addons' , array( $this , 'ajax_nopriv_get_addons' ) );
|
36 |
-
add_action( 'wp_ajax_rtb-addons', array( $this, 'ajax_get_addons' ) );
|
37 |
|
38 |
-
|
39 |
-
|
40 |
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Parse the arguments passed in the construction and assign them to
|
46 |
-
* internal variables.
|
47 |
-
*/
|
48 |
-
private function parse_args( $args ) {
|
49 |
-
foreach ( $args as $key => $val ) {
|
50 |
-
switch ( $key ) {
|
51 |
-
|
52 |
-
case 'api_url' :
|
53 |
-
$this->{$key} = esc_url( $val );
|
54 |
-
|
55 |
-
case 'plugin' :
|
56 |
-
$this->{$key} = esc_attr( $val );
|
57 |
-
|
58 |
-
default :
|
59 |
-
$this->{$key} = $val;
|
60 |
-
|
61 |
-
}
|
62 |
-
}
|
63 |
-
|
64 |
-
do_action( $this->plugin . '_addons_parse_args' );
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Check that we have everything we need to render the addons page
|
69 |
-
*/
|
70 |
-
public function check_config() {
|
71 |
-
|
72 |
-
if ( !empty( $this->api_url ) && !empty( $this->plugin ) ) {
|
73 |
-
return true;
|
74 |
-
}
|
75 |
-
|
76 |
-
return false;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Send addon data to the javascript
|
81 |
-
*/
|
82 |
-
public function enqueue_admin_assets() {
|
83 |
-
|
84 |
-
// Use the page reference in $admin_page_hooks because
|
85 |
-
// it changes in SOME hooks when it is translated.
|
86 |
-
// https://core.trac.wordpress.org/ticket/18857
|
87 |
-
global $admin_page_hooks;
|
88 |
-
|
89 |
-
$screen = get_current_screen();
|
90 |
-
if ( empty( $screen ) || empty( $admin_page_hooks['rtb-bookings'] ) ) {
|
91 |
-
return;
|
92 |
-
}
|
93 |
-
|
94 |
-
if ( $screen->base == $admin_page_hooks['rtb-bookings'] . '_page_rtb-addons' ) {
|
95 |
-
wp_localize_script(
|
96 |
-
'rtb-admin',
|
97 |
-
'rtb_addons',
|
98 |
-
array(
|
99 |
-
'nonce' => wp_create_nonce( 'rtb-addons' ),
|
100 |
-
'strings' => array(
|
101 |
-
'loading' => __( 'Loading', 'restaurant-reservations' ),
|
102 |
-
'error_unknown' => _x( 'An unknown error occured.', 'Error message when retrieving list of addons', 'restaurant-reservations' ),
|
103 |
-
'installed' => _x( 'Already Installed', 'Label for an addon that is already installed and activated.', 'restaurant-reservations' ),
|
104 |
-
'coming_soon' => _x( 'Coming Soon', 'Label for an addon that is not yet released.', 'restaurant-reservations' ),
|
105 |
-
'free' => _x( 'Free', 'Label for an addon that is free.', 'restaurant-reservations' ),
|
106 |
-
'learn_more' => _x( 'Get It', 'Label for an addon that is released.', 'restaurant-reservations' ),
|
107 |
-
)
|
108 |
-
)
|
109 |
-
);
|
110 |
-
}
|
111 |
}
|
112 |
|
113 |
/**
|
@@ -131,16 +39,77 @@ class rtbAddons {
|
|
131 |
*/
|
132 |
public function show_admin_addons_page() {
|
133 |
|
134 |
-
//
|
|
|
135 |
?>
|
136 |
|
137 |
<div class="wrap">
|
138 |
<h1><?php _e( 'Addons for Restaurant Reservations', 'restaurant-reservations' ); ?></h1>
|
139 |
<?php do_action( 'rtb_addons_pre' ); ?>
|
140 |
-
<div
|
141 |
-
<div class="
|
142 |
-
<
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
</div>
|
145 |
</div>
|
146 |
<?php do_action( 'rtb_addons_post' ); ?>
|
@@ -149,64 +118,6 @@ class rtbAddons {
|
|
149 |
<?php
|
150 |
}
|
151 |
|
152 |
-
/**
|
153 |
-
* Handle ajax request for addons from logged out user
|
154 |
-
*/
|
155 |
-
public function ajax_nopriv_get_addons() {
|
156 |
-
|
157 |
-
wp_send_json_error(
|
158 |
-
array(
|
159 |
-
'error' => 'loggedout',
|
160 |
-
'msg' => __( 'You have been logged out. Please login again to retrieve the addons.', 'restaurant-reservations' ),
|
161 |
-
)
|
162 |
-
);
|
163 |
-
}
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Handle ajax request for addons
|
167 |
-
*/
|
168 |
-
public function ajax_get_addons() {
|
169 |
-
|
170 |
-
$url = $this->api_url . $this->plugin;
|
171 |
-
|
172 |
-
if ( !check_ajax_referer( 'rtb-addons', 'nonce' ) || !current_user_can( 'manage_options' )) {
|
173 |
-
wp_send_json_error(
|
174 |
-
array(
|
175 |
-
'error' => 'nopriv',
|
176 |
-
'msg' => __( 'You do not have permission to access this page. Please login to an administrator account if you have one.', 'restaurant-reservations' ),
|
177 |
-
)
|
178 |
-
);
|
179 |
-
}
|
180 |
-
|
181 |
-
if ( function_exists( 'curl_init' ) && function_exists( 'curl_setop' ) ) {
|
182 |
-
$ch = curl_init();
|
183 |
-
curl_setopt( $ch, CURLOPT_URL, $url );
|
184 |
-
curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' ) );
|
185 |
-
curl_setopt( $ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0' );
|
186 |
-
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
|
187 |
-
curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );
|
188 |
-
$result = curl_exec($ch);
|
189 |
-
curl_close($ch);
|
190 |
-
|
191 |
-
} elseif ( ini_get( 'allow_url_fopen' ) ) {
|
192 |
-
$result = @file_get_contents( $url );
|
193 |
-
} else {
|
194 |
-
$result = @file_get_contents( RTB_PLUGIN_DIR . '/assets/addons-backup.json' );
|
195 |
-
}
|
196 |
-
|
197 |
-
if ( $result ) {
|
198 |
-
// @todo set a transient with this data to reduce calls
|
199 |
-
wp_send_json_success( json_decode( $result ) );
|
200 |
-
} else {
|
201 |
-
wp_send_json_error(
|
202 |
-
array(
|
203 |
-
'error' => 'apifailed',
|
204 |
-
'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' ),
|
205 |
-
)
|
206 |
-
);
|
207 |
-
}
|
208 |
-
}
|
209 |
-
|
210 |
/**
|
211 |
* Add a prompt for users to subscribe to the Theme of the Crop mailing list
|
212 |
* below the addons list.
|
@@ -218,7 +129,17 @@ class rtbAddons {
|
|
218 |
?>
|
219 |
|
220 |
<p>
|
221 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
</p>
|
223 |
|
224 |
<?php
|
9 |
*/
|
10 |
class rtbAddons {
|
11 |
|
12 |
+
public function __construct( ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
+
// Add the admin menu
|
15 |
+
add_action( 'admin_menu', array( $this, 'add_menu_page' ), 100 );
|
16 |
|
17 |
+
// Add a newsletter subscription prompt above the addons
|
18 |
+
add_action( 'rtb_addons_pre', array( $this, 'add_subscribe_pompt' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
}
|
20 |
|
21 |
/**
|
39 |
*/
|
40 |
public function show_admin_addons_page() {
|
41 |
|
42 |
+
// Set campaign parameters for addon URLs
|
43 |
+
$url_params = '?utm_source=Plugin&utm_medium=Addon%20List&utm_campaign=Restaurant%20Reservations';
|
44 |
?>
|
45 |
|
46 |
<div class="wrap">
|
47 |
<h1><?php _e( 'Addons for Restaurant Reservations', 'restaurant-reservations' ); ?></h1>
|
48 |
<?php do_action( 'rtb_addons_pre' ); ?>
|
49 |
+
<div class="rtb-addons">
|
50 |
+
<div class="addon addon-custom-fields">
|
51 |
+
<a href="https://themeofthecrop.com/plugins/restaurant-reservations/custom-fields/<?php echo $url_params; ?>">
|
52 |
+
<img src="<?php echo RTB_PLUGIN_URL . '/assets/img/custom-fields.png'; ?>">
|
53 |
+
</a>
|
54 |
+
<h3><?php echo esc_html( 'Custom Fields', 'restaurant-reservations' ); ?></h3>
|
55 |
+
<div class="details">
|
56 |
+
<div class="description">
|
57 |
+
<?php echo esc_html( 'Plan your dinner service better by asking for special seating requests, dietary needs and more when customers book online.', 'restaurant-reservations' ); ?>
|
58 |
+
</div>
|
59 |
+
<div class="action">
|
60 |
+
<a href="https://themeofthecrop.com/plugins/restaurant-reservations/custom-fields/<?php echo $url_params; ?>" class="button button-primary" target="_blank">
|
61 |
+
<?php echo esc_html( 'Learn More', 'restaurant-reservations' ); ?>
|
62 |
+
</a>
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
</div>
|
66 |
+
<div class="addon addon-export-bookings">
|
67 |
+
<a href="https://themeofthecrop.com/plugins/restaurant-reservations/export-bookings/<?php echo $url_params; ?>">
|
68 |
+
<img src="<?php echo RTB_PLUGIN_URL . '/assets/img/export-bookings.png'; ?>">
|
69 |
+
</a>
|
70 |
+
<h3><?php echo esc_html( 'Export Bookings', 'restaurant-reservations' ); ?></h3>
|
71 |
+
<div class="details">
|
72 |
+
<div class="description">
|
73 |
+
<?php echo esc_html( 'Easily print your bookings in a PDF or export them to an Excel/CSV file so you can analyze patterns, cull customer data and import bookings into other services.' ); ?>
|
74 |
+
</div>
|
75 |
+
<div class="action">
|
76 |
+
<a href="https://themeofthecrop.com/plugins/restaurant-reservations/export-bookings/<?php echo $url_params; ?>" class="button button-primary" target="_blank">
|
77 |
+
<?php echo esc_html( 'Learn More', 'restaurant-reservations' ); ?>
|
78 |
+
</a>
|
79 |
+
</div>
|
80 |
+
</div>
|
81 |
+
</div>
|
82 |
+
<div class="addon addon-mailchimp">
|
83 |
+
<a href="https://themeofthecrop.com/plugins/restaurant-reservations/mailchimp/<?php echo $url_params; ?>">
|
84 |
+
<img src="<?php echo RTB_PLUGIN_URL . '/assets/img/mailchimp.png'; ?>">
|
85 |
+
</a>
|
86 |
+
<h3><?php echo esc_html( 'MailChimp', 'restaurant-reservations' ); ?></h3>
|
87 |
+
<div class="details">
|
88 |
+
<div class="description">
|
89 |
+
<?php echo esc_html( 'Subscribe requests to your MailChimp mailing list and watch your subscription rates grow effortlessly.' ); ?>
|
90 |
+
</div>
|
91 |
+
<div class="action">
|
92 |
+
<a href="https://themeofthecrop.com/plugins/restaurant-reservations/mailchimp/<?php echo $url_params; ?>" class="button button-primary" target="_blank">
|
93 |
+
<?php echo esc_html( 'Learn More', 'restaurant-reservations' ); ?>
|
94 |
+
</a>
|
95 |
+
</div>
|
96 |
+
</div>
|
97 |
+
</div>
|
98 |
+
<div class="addon addon-themes">
|
99 |
+
<a href="https://themeofthecrop.com/themes/<?php echo $url_params; ?>">
|
100 |
+
<img src="<?php echo RTB_PLUGIN_URL . '/assets/img/themes.png'; ?>">
|
101 |
+
</a>
|
102 |
+
<h3><?php echo esc_html( 'Restaurant WordPress Themes', 'restaurant-reservations' ); ?></h3>
|
103 |
+
<div class="details">
|
104 |
+
<div class="description">
|
105 |
+
<?php echo esc_html( 'Find the best WordPress restaurant themes that integrate beautifully with your reservations plugin.' ); ?>
|
106 |
+
</div>
|
107 |
+
<div class="action">
|
108 |
+
<a href="https://themeofthecrop.com/themes/<?php echo $url_params; ?>" class="button" target="_blank">
|
109 |
+
<?php echo esc_html( 'View Themes', 'restaurant-reservations' ); ?>
|
110 |
+
</a>
|
111 |
+
</div>
|
112 |
+
</div>
|
113 |
</div>
|
114 |
</div>
|
115 |
<?php do_action( 'rtb_addons_post' ); ?>
|
118 |
<?php
|
119 |
}
|
120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
/**
|
122 |
* Add a prompt for users to subscribe to the Theme of the Crop mailing list
|
123 |
* below the addons list.
|
129 |
?>
|
130 |
|
131 |
<p>
|
132 |
+
<?php
|
133 |
+
echo sprintf(
|
134 |
+
esc_html_x( 'Find out when new addons are available by subscribing to the %smonthly newsletter%s, liking %sTheme of the Crop%s on Facebook, or following %sTheme of the Crop%s on Twitter.', 'restaurant-reservations' ),
|
135 |
+
'<a target="_blank" href="https://themeofthecrop.com/about/mailing-list/?utm_source=Plugin&utm_medium=Addon%20List&utm_campaign=Restaurant%20Reservations">',
|
136 |
+
'</a>',
|
137 |
+
'<a target="_blank" href="https://www.facebook.com/themeofthecrop/">',
|
138 |
+
'</a>',
|
139 |
+
'<a target="_blank" href="http://twitter.com/themeofthecrop">',
|
140 |
+
'</a>'
|
141 |
+
);
|
142 |
+
?>
|
143 |
</p>
|
144 |
|
145 |
<?php
|
includes/AdminBookings.class.php
CHANGED
@@ -38,6 +38,8 @@ class rtbAdminBookings {
|
|
38 |
add_action( 'wp_ajax_rtb-admin-email-modal', array( $this, 'email_modal_ajax' ) );
|
39 |
add_action( 'wp_ajax_nopriv_rtb-admin-column-modal' , array( $this , 'nopriv_ajax' ) );
|
40 |
add_action( 'wp_ajax_rtb-admin-column-modal', array( $this, 'column_modal_ajax' ) );
|
|
|
|
|
41 |
|
42 |
// Validate post status and notification fields
|
43 |
add_action( 'rtb_validate_booking_submission', array( $this, 'validate_admin_fields' ) );
|
@@ -270,6 +272,39 @@ class rtbAdminBookings {
|
|
270 |
</div>
|
271 |
</div>
|
272 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
<!-- Restaurant Reservations error message modal -->
|
274 |
<div id="rtb-error-modal" class="rtb-admin-modal">
|
275 |
<div class="rtb-error rtb-container">
|
@@ -616,7 +651,9 @@ class rtbAdminBookings {
|
|
616 |
$email->message = $message;
|
617 |
$email->set_booking( $booking );
|
618 |
if ( $email->prepare_notification() ) {
|
|
|
619 |
$email->send_notification();
|
|
|
620 |
}
|
621 |
|
622 |
// Store email in postmeta for log
|
@@ -656,6 +693,55 @@ class rtbAdminBookings {
|
|
656 |
wp_send_json_success();
|
657 |
}
|
658 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
659 |
/**
|
660 |
* Validate post status and notification fields
|
661 |
* @since 1.3
|
38 |
add_action( 'wp_ajax_rtb-admin-email-modal', array( $this, 'email_modal_ajax' ) );
|
39 |
add_action( 'wp_ajax_nopriv_rtb-admin-column-modal' , array( $this , 'nopriv_ajax' ) );
|
40 |
add_action( 'wp_ajax_rtb-admin-column-modal', array( $this, 'column_modal_ajax' ) );
|
41 |
+
add_action( 'wp_ajax_nopriv_rtb-admin-ban-modal' , array( $this , 'nopriv_ajax' ) );
|
42 |
+
add_action( 'wp_ajax_rtb-admin-ban-modal', array( $this, 'ban_modal_ajax' ) );
|
43 |
|
44 |
// Validate post status and notification fields
|
45 |
add_action( 'rtb_validate_booking_submission', array( $this, 'validate_admin_fields' ) );
|
272 |
</div>
|
273 |
</div>
|
274 |
|
275 |
+
<!-- Restaurant Reservations ban email/ip modal -->
|
276 |
+
<div id="rtb-ban-modal" class="rtb-admin-modal">
|
277 |
+
<div class="rtb-ban-form rtb-container">
|
278 |
+
<div class="rtb-ban-msg">
|
279 |
+
<p class="intro">
|
280 |
+
<?php
|
281 |
+
printf(
|
282 |
+
__( 'Ban future bookings from the email address %s or the IP address %s?', 'restaurant-reservations' ),
|
283 |
+
'<span id="rtb-ban-modal-email"></span>',
|
284 |
+
'<span id="rtb-ban-modal-ip"></span>'
|
285 |
+
);
|
286 |
+
?>
|
287 |
+
</p>
|
288 |
+
<p>
|
289 |
+
<?php
|
290 |
+
esc_html_e( 'It is recommended to ban by email address instead of IP. Only ban by IP address to block a malicious user who is using different email addresses to avoid a previous ban.', 'restaurant-reservations' );
|
291 |
+
?>
|
292 |
+
</p>
|
293 |
+
</div>
|
294 |
+
<button class="button button-primary" id="rtb-ban-modal-email-btn">Ban Email</button>
|
295 |
+
<button class="button button-primary" id="rtb-ban-modal-ip-btn">Ban IP</button>
|
296 |
+
<a href="#" id="rtb-cancel-ban-modal" class="button"><?php _e( 'Close', 'restaurant-reservations' ); ?></a>
|
297 |
+
<a class="button-link" href="<?php echo esc_url( admin_url( '/admin.php?page=rtb-settings' ) ); ?>" target="_blank">
|
298 |
+
<?php esc_html_e( 'View all bans', 'restaurant-reservations' ); ?>
|
299 |
+
</a>
|
300 |
+
<div class="action-status">
|
301 |
+
<span class="spinner loading"></span>
|
302 |
+
<span class="dashicons dashicons-no-alt error"></span>
|
303 |
+
<span class="dashicons dashicons-yes success"></span>
|
304 |
+
</div>
|
305 |
+
</div>
|
306 |
+
</div>
|
307 |
+
|
308 |
<!-- Restaurant Reservations error message modal -->
|
309 |
<div id="rtb-error-modal" class="rtb-admin-modal">
|
310 |
<div class="rtb-error rtb-container">
|
651 |
$email->message = $message;
|
652 |
$email->set_booking( $booking );
|
653 |
if ( $email->prepare_notification() ) {
|
654 |
+
do_action( 'rtb_send_notification_before', $email );
|
655 |
$email->send_notification();
|
656 |
+
do_action( 'rtb_send_notification_after', $email );
|
657 |
}
|
658 |
|
659 |
// Store email in postmeta for log
|
693 |
wp_send_json_success();
|
694 |
}
|
695 |
|
696 |
+
/**
|
697 |
+
* Handle ajax requests to ban by IP or email address
|
698 |
+
*
|
699 |
+
* @since 1.3.1
|
700 |
+
*/
|
701 |
+
public function ban_modal_ajax() {
|
702 |
+
|
703 |
+
global $rtb_controller;
|
704 |
+
|
705 |
+
// Authenticate request
|
706 |
+
if ( !check_ajax_referer( 'rtb-admin', 'nonce' ) || !current_user_can( 'manage_bookings' ) ) {
|
707 |
+
$this->nopriv_ajax();
|
708 |
+
}
|
709 |
+
|
710 |
+
// Ban an email address
|
711 |
+
if ( isset( $_POST['email'] ) && !empty( $_POST['email'] ) ) {
|
712 |
+
$email = trim( sanitize_text_field( $_POST['email'] ) );
|
713 |
+
$banned_emails = preg_split( '/\r\n|\r|\n/', (string) $rtb_controller->settings->get_setting( 'ban-emails' ) );
|
714 |
+
|
715 |
+
if ( !in_array( $email, $banned_emails ) ) {
|
716 |
+
$banned_emails[] = $email;
|
717 |
+
$rtb_controller->settings->settings['ban-emails'] = join( "\n", $banned_emails );
|
718 |
+
update_option( 'rtb-settings', $rtb_controller->settings->settings );
|
719 |
+
}
|
720 |
+
|
721 |
+
wp_send_json_success();
|
722 |
+
|
723 |
+
// Ban an IP address
|
724 |
+
} elseif ( isset( $_POST['ip'] ) && !empty( $_POST['ip'] ) ) {
|
725 |
+
$ip = trim( sanitize_text_field( $_POST['ip'] ) );
|
726 |
+
$banned_ips = preg_split( '/\r\n|\r|\n/', (string) $rtb_controller->settings->get_setting( 'ban-ips' ) );
|
727 |
+
|
728 |
+
if ( !in_array( $ip, $banned_ips ) ) {
|
729 |
+
$banned_ips[] = $ip;
|
730 |
+
$rtb_controller->settings->settings['ban-ips'] = join( "\n", $banned_ips );
|
731 |
+
update_option( 'rtb-settings', $rtb_controller->settings->settings );
|
732 |
+
}
|
733 |
+
|
734 |
+
wp_send_json_success();
|
735 |
+
}
|
736 |
+
|
737 |
+
wp_send_json_error(
|
738 |
+
array(
|
739 |
+
'error' => 'no_data',
|
740 |
+
'msg' => __( 'No IP or email address could be found for this ban request.', 'restaurant-reservations' ),
|
741 |
+
)
|
742 |
+
);
|
743 |
+
}
|
744 |
+
|
745 |
/**
|
746 |
* Validate post status and notification fields
|
747 |
* @since 1.3
|
includes/Booking.class.php
CHANGED
@@ -80,6 +80,7 @@ class rtbBooking {
|
|
80 |
'phone' => '',
|
81 |
'date_submission' => '',
|
82 |
'logs' => array(),
|
|
|
83 |
);
|
84 |
|
85 |
$meta_defaults = apply_filters( 'rtb_booking_metadata_defaults', $meta_defaults );
|
@@ -95,6 +96,7 @@ class rtbBooking {
|
|
95 |
$this->phone = $meta['phone'];
|
96 |
$this->date_submission = $meta['date_submission'];
|
97 |
$this->logs = $meta['logs'];
|
|
|
98 |
}
|
99 |
|
100 |
/**
|
@@ -243,6 +245,15 @@ class rtbBooking {
|
|
243 |
);
|
244 |
}
|
245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
} else {
|
247 |
$late_bookings_seconds = $late_bookings * 60; // Late bookings allowance in seconds
|
248 |
if ( $request->format( 'U' ) < ( current_time( 'timestamp' ) + $late_bookings_seconds ) ) {
|
@@ -264,7 +275,7 @@ class rtbBooking {
|
|
264 |
|
265 |
// Check against scheduling exception rules
|
266 |
$exceptions = $rtb_controller->settings->get_setting( 'schedule-closed' );
|
267 |
-
if ( empty( $this->validation_errors ) && !empty( $exceptions ) ) {
|
268 |
$exception_is_active = false;
|
269 |
$datetime_is_valid = false;
|
270 |
foreach( $exceptions as $exception ) {
|
@@ -298,7 +309,7 @@ class rtbBooking {
|
|
298 |
|
299 |
// Check against weekly scheduling rules
|
300 |
$rules = $rtb_controller->settings->get_setting( 'schedule-open' );
|
301 |
-
if ( empty( $exception_is_active ) && empty( $this->validation_errors ) && !empty( $rules ) ) {
|
302 |
$request_weekday = strtolower( $request->format( 'l' ) );
|
303 |
$time_is_valid = null;
|
304 |
$day_is_valid = null;
|
@@ -394,6 +405,14 @@ class rtbBooking {
|
|
394 |
'message' => sprintf( __( 'We only accept bookings for parties of up to %d people.', 'restaurant-reservations' ), $party_size ),
|
395 |
);
|
396 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
}
|
398 |
|
399 |
// Email/Phone
|
@@ -429,6 +448,22 @@ class rtbBooking {
|
|
429 |
}
|
430 |
}
|
431 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
432 |
do_action( 'rtb_validate_booking_submission', $this );
|
433 |
|
434 |
}
|
@@ -482,6 +517,64 @@ class rtbBooking {
|
|
482 |
return false;
|
483 |
}
|
484 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
485 |
/**
|
486 |
* Add a log entry to the booking
|
487 |
*
|
@@ -534,6 +627,7 @@ class rtbBooking {
|
|
534 |
'email' => $this->email,
|
535 |
'phone' => $this->phone,
|
536 |
'date_submission' => current_time( 'timestamp' ),
|
|
|
537 |
);
|
538 |
|
539 |
if ( !empty( $this->logs ) ) {
|
80 |
'phone' => '',
|
81 |
'date_submission' => '',
|
82 |
'logs' => array(),
|
83 |
+
'ip' => '',
|
84 |
);
|
85 |
|
86 |
$meta_defaults = apply_filters( 'rtb_booking_metadata_defaults', $meta_defaults );
|
96 |
$this->phone = $meta['phone'];
|
97 |
$this->date_submission = $meta['date_submission'];
|
98 |
$this->logs = $meta['logs'];
|
99 |
+
$this->ip = $meta['ip'];
|
100 |
}
|
101 |
|
102 |
/**
|
245 |
);
|
246 |
}
|
247 |
|
248 |
+
} elseif ( $late_bookings === 'same_day' ) {
|
249 |
+
if ( $request->format( 'Y-m-d' ) == current_time( 'Y-m-d' ) ) {
|
250 |
+
$this->validation_errors[] = array(
|
251 |
+
'field' => 'time',
|
252 |
+
'error_msg' => 'Booking request made on same day',
|
253 |
+
'message' => __( 'Sorry, bookings can not be made for the same day.', 'restaurant-reservations' ),
|
254 |
+
);
|
255 |
+
}
|
256 |
+
|
257 |
} else {
|
258 |
$late_bookings_seconds = $late_bookings * 60; // Late bookings allowance in seconds
|
259 |
if ( $request->format( 'U' ) < ( current_time( 'timestamp' ) + $late_bookings_seconds ) ) {
|
275 |
|
276 |
// Check against scheduling exception rules
|
277 |
$exceptions = $rtb_controller->settings->get_setting( 'schedule-closed' );
|
278 |
+
if ( empty( $this->validation_errors ) && !empty( $exceptions ) && !current_user_can( 'manage_bookings' ) ) {
|
279 |
$exception_is_active = false;
|
280 |
$datetime_is_valid = false;
|
281 |
foreach( $exceptions as $exception ) {
|
309 |
|
310 |
// Check against weekly scheduling rules
|
311 |
$rules = $rtb_controller->settings->get_setting( 'schedule-open' );
|
312 |
+
if ( empty( $exception_is_active ) && empty( $this->validation_errors ) && !empty( $rules ) && !current_user_can( 'manage_bookings' ) ) {
|
313 |
$request_weekday = strtolower( $request->format( 'l' ) );
|
314 |
$time_is_valid = null;
|
315 |
$day_is_valid = null;
|
405 |
'message' => sprintf( __( 'We only accept bookings for parties of up to %d people.', 'restaurant-reservations' ), $party_size ),
|
406 |
);
|
407 |
}
|
408 |
+
$party_size_min = $rtb_controller->settings->get_setting( 'party-size-min' );
|
409 |
+
if ( !empty( $party_size_min ) && $party_size_min > $this->party ) {
|
410 |
+
$this->validation_errors[] = array(
|
411 |
+
'field' => 'party',
|
412 |
+
'post_variable' => $this->party,
|
413 |
+
'message' => sprintf( __( 'We only accept bookings for parties of more than %d people.', 'restaurant-reservations' ), $party_size_min ),
|
414 |
+
);
|
415 |
+
}
|
416 |
}
|
417 |
|
418 |
// Email/Phone
|
448 |
}
|
449 |
}
|
450 |
|
451 |
+
// Check if the email or IP is banned
|
452 |
+
if ( !current_user_can( 'manage_bookings' ) ) {
|
453 |
+
$ip = $_SERVER['REMOTE_ADDR'];
|
454 |
+
if ( !$this->is_valid_ip( $ip ) || !$this->is_valid_email( $this->email ) ) {
|
455 |
+
$this->validation_errors[] = array(
|
456 |
+
'field' => 'date',
|
457 |
+
'post_variable' => $ip,
|
458 |
+
'message' => __( 'Your booking has been rejected. Please call us if you would like to make a booking.', 'restaurant-reservations' ),
|
459 |
+
);
|
460 |
+
} elseif ( empty( $this->ip ) ) {
|
461 |
+
$this->ip = sanitize_text_field( $ip );
|
462 |
+
}
|
463 |
+
} elseif ( empty( $this->ip ) ) {
|
464 |
+
$this->ip = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
|
465 |
+
}
|
466 |
+
|
467 |
do_action( 'rtb_validate_booking_submission', $this );
|
468 |
|
469 |
}
|
517 |
return false;
|
518 |
}
|
519 |
|
520 |
+
/**
|
521 |
+
* Check if an IP address has been banned
|
522 |
+
*
|
523 |
+
* @param string $ip
|
524 |
+
* @return bool
|
525 |
+
* @since 1.7
|
526 |
+
*/
|
527 |
+
public function is_valid_ip( $ip = null ) {
|
528 |
+
|
529 |
+
if ( is_null( $ip ) ) {
|
530 |
+
$ip = isset( $this->ip ) ? $this->ip : null;
|
531 |
+
if ( is_null( $ip ) ) {
|
532 |
+
return false;
|
533 |
+
}
|
534 |
+
}
|
535 |
+
|
536 |
+
global $rtb_controller;
|
537 |
+
|
538 |
+
$banned_ips = array_filter( explode( "\n", $rtb_controller->settings->get_setting( 'ban-ips' ) ) );
|
539 |
+
|
540 |
+
foreach( $banned_ips as $banned_ip ) {
|
541 |
+
if ( $ip == trim( $banned_ip ) ) {
|
542 |
+
return false;
|
543 |
+
}
|
544 |
+
}
|
545 |
+
|
546 |
+
return true;
|
547 |
+
}
|
548 |
+
|
549 |
+
/**
|
550 |
+
* Check if an email address has been banned
|
551 |
+
*
|
552 |
+
* @param string $email
|
553 |
+
* @return bool
|
554 |
+
* @since 1.7
|
555 |
+
*/
|
556 |
+
public function is_valid_email( $email = null ) {
|
557 |
+
|
558 |
+
if ( is_null( $email ) ) {
|
559 |
+
$email = isset( $this->email ) ? $this->email : null;
|
560 |
+
if ( is_null( $email ) ) {
|
561 |
+
return false;
|
562 |
+
}
|
563 |
+
}
|
564 |
+
|
565 |
+
global $rtb_controller;
|
566 |
+
|
567 |
+
$banned_emails = array_filter( explode( "\n", $rtb_controller->settings->get_setting( 'ban-emails' ) ) );
|
568 |
+
|
569 |
+
foreach( $banned_emails as $banned_email ) {
|
570 |
+
if ( $email == trim( $banned_email ) ) {
|
571 |
+
return false;
|
572 |
+
}
|
573 |
+
}
|
574 |
+
|
575 |
+
return true;
|
576 |
+
}
|
577 |
+
|
578 |
/**
|
579 |
* Add a log entry to the booking
|
580 |
*
|
627 |
'email' => $this->email,
|
628 |
'phone' => $this->phone,
|
629 |
'date_submission' => current_time( 'timestamp' ),
|
630 |
+
'ip' => $this->ip,
|
631 |
);
|
632 |
|
633 |
if ( !empty( $this->logs ) ) {
|
includes/Compatibility.class.php
CHANGED
@@ -15,9 +15,10 @@ class rtbCompatibility {
|
|
15 |
*/
|
16 |
public function __construct() {
|
17 |
|
18 |
-
// Preserve
|
19 |
// to check if the plugin was active
|
20 |
define( 'RTB_TEXTDOMAIN', 'rtbdomain' );
|
|
|
21 |
|
22 |
// Load a .mo file for an old textdomain if one exists
|
23 |
add_filter( 'load_textdomain_mofile', array( $this, 'load_old_textdomain' ), 10, 2 );
|
15 |
*/
|
16 |
public function __construct() {
|
17 |
|
18 |
+
// Preserve defined constants in case anyone relied on them
|
19 |
// to check if the plugin was active
|
20 |
define( 'RTB_TEXTDOMAIN', 'rtbdomain' );
|
21 |
+
define( 'RTB_LOAD_FRONTEND_ASSETS', apply_filters( 'rtb-load-frontend-assets', true ) );
|
22 |
|
23 |
// Load a .mo file for an old textdomain if one exists
|
24 |
add_filter( 'load_textdomain_mofile', array( $this, 'load_old_textdomain' ), 10, 2 );
|
includes/MultipleLocations.class.php
CHANGED
@@ -81,7 +81,6 @@ if ( ! class_exists( 'rtbMultipleLocations', false ) ) {
|
|
81 |
add_filter( 'rtb_query_args', array( $this, 'modify_query' ), 10, 2 );
|
82 |
add_filter( 'rtb_bookings_all_table_columns', array( $this, 'add_location_column' ) );
|
83 |
add_filter( 'rtb_bookings_table_column', array( $this, 'print_location_column' ), 10, 3 );
|
84 |
-
add_filter( 'rtb_bookings_table_column_details', array( $this, 'add_details_column_items' ), 10, 2 );
|
85 |
add_action( 'edit_form_after_title', array( $this, 'add_meta_nonce' ) );
|
86 |
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
|
87 |
add_filter( 'the_content', array( $this, 'append_to_content' ) );
|
@@ -431,32 +430,6 @@ if ( ! class_exists( 'rtbMultipleLocations', false ) ) {
|
|
431 |
return $location->name;
|
432 |
}
|
433 |
|
434 |
-
/**
|
435 |
-
* Add the location to the details column if the column has been
|
436 |
-
* hidden
|
437 |
-
*
|
438 |
-
* @since 1.6
|
439 |
-
*/
|
440 |
-
public function add_details_column_items( $details, $booking ) {
|
441 |
-
|
442 |
-
global $rtb_controller;
|
443 |
-
|
444 |
-
$visible_columns = $rtb_controller->bookings->bookings_table->get_columns();
|
445 |
-
if ( !isset( $visible_columns['location'] ) ) {
|
446 |
-
|
447 |
-
$value = $rtb_controller->bookings->bookings_table->column_default( $booking, 'location' );
|
448 |
-
|
449 |
-
if ( !empty( $value ) ) {
|
450 |
-
$details[] = array(
|
451 |
-
'label' => __( 'Location', 'restaurant-reservations' ),
|
452 |
-
'value' => $value,
|
453 |
-
);
|
454 |
-
}
|
455 |
-
}
|
456 |
-
|
457 |
-
return $details;
|
458 |
-
}
|
459 |
-
|
460 |
/**
|
461 |
* Modify queries to add location taxonomy parameters
|
462 |
*
|
81 |
add_filter( 'rtb_query_args', array( $this, 'modify_query' ), 10, 2 );
|
82 |
add_filter( 'rtb_bookings_all_table_columns', array( $this, 'add_location_column' ) );
|
83 |
add_filter( 'rtb_bookings_table_column', array( $this, 'print_location_column' ), 10, 3 );
|
|
|
84 |
add_action( 'edit_form_after_title', array( $this, 'add_meta_nonce' ) );
|
85 |
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
|
86 |
add_filter( 'the_content', array( $this, 'append_to_content' ) );
|
430 |
return $location->name;
|
431 |
}
|
432 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
433 |
/**
|
434 |
* Modify queries to add location taxonomy parameters
|
435 |
*
|
includes/Notifications.class.php
CHANGED
@@ -171,7 +171,9 @@ class rtbNotifications {
|
|
171 |
if ( $event == $notification->event ) {
|
172 |
$notification->set_booking( $this->booking );
|
173 |
if ( $notification->prepare_notification() ) {
|
|
|
174 |
$notification->send_notification();
|
|
|
175 |
}
|
176 |
}
|
177 |
}
|
171 |
if ( $event == $notification->event ) {
|
172 |
$notification->set_booking( $this->booking );
|
173 |
if ( $notification->prepare_notification() ) {
|
174 |
+
do_action( 'rtb_send_notification_before', $notification );
|
175 |
$notification->send_notification();
|
176 |
+
do_action( 'rtb_send_notification_after', $notification );
|
177 |
}
|
178 |
}
|
179 |
}
|
includes/Settings.class.php
CHANGED
@@ -90,8 +90,8 @@ class rtbSettings {
|
|
90 |
$this->defaults = array(
|
91 |
|
92 |
'success-message' => _x( 'Thanks, your booking request is waiting to be confirmed. Updates will be sent to the email address you provided.', 'restaurant-reservations' ),
|
93 |
-
'date-format' => _x( 'mmmm d, yyyy', 'Default date format for display. Must match formatting rules at http://amsul.ca/pickadate.js/date
|
94 |
-
'time-format' => _x( 'h:i A', 'Default time format for display. Must match formatting rules at http://amsul.ca/pickadate.js/time
|
95 |
'time-interval' => _x( '30', 'Default interval in minutes when selecting a time.', 'restaurant-reservations' ),
|
96 |
|
97 |
// Email address where admin notifications should be sent
|
@@ -262,6 +262,19 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
|
|
262 |
)
|
263 |
);
|
264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
$sap->add_setting(
|
266 |
'rtb-settings',
|
267 |
'rtb-general',
|
@@ -294,7 +307,7 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
|
|
294 |
array(
|
295 |
'id' => 'date-format',
|
296 |
'title' => __( 'Date Format', 'restaurant-reservations' ),
|
297 |
-
'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
|
298 |
'placeholder' => $this->defaults['date-format'],
|
299 |
)
|
300 |
);
|
@@ -306,13 +319,13 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
|
|
306 |
array(
|
307 |
'id' => 'time-format',
|
308 |
'title' => __( 'Time Format', 'restaurant-reservations' ),
|
309 |
-
'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
|
310 |
'placeholder' => $this->defaults['time-format'],
|
311 |
)
|
312 |
);
|
313 |
|
314 |
// Add i8n setting for pickadate if the frontend assets are to be loaded
|
315 |
-
if (
|
316 |
$sap->add_setting(
|
317 |
'rtb-settings',
|
318 |
'rtb-general',
|
@@ -326,6 +339,28 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
|
|
326 |
);
|
327 |
}
|
328 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
$sap->add_section(
|
330 |
'rtb-settings',
|
331 |
array(
|
@@ -434,13 +469,14 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
|
|
434 |
'description' => __( 'Select how late customers can make their booking. (Administrators and Booking Managers are not restricted by this setting.)', 'restaurant-reservations' ),
|
435 |
'blank_option' => false,
|
436 |
'options' => array(
|
437 |
-
''
|
438 |
-
'15'
|
439 |
-
'30'
|
440 |
-
'45'
|
441 |
-
'60'
|
442 |
-
'240'
|
443 |
-
'1440'
|
|
|
444 |
)
|
445 |
)
|
446 |
);
|
@@ -693,11 +729,13 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
|
|
693 |
* Get options for the party size setting
|
694 |
* @since 1.3
|
695 |
*/
|
696 |
-
public function get_party_size_setting_options
|
697 |
|
698 |
-
$options = array
|
699 |
-
|
700 |
-
|
|
|
|
|
701 |
|
702 |
$max = apply_filters( 'rtb_party_size_upper_limit', 100 );
|
703 |
|
@@ -715,10 +753,12 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
|
|
715 |
public function get_form_party_options() {
|
716 |
|
717 |
$party_size = (int) $this->get_setting( 'party-size' );
|
|
|
718 |
|
|
|
719 |
$max = empty( $party_size ) ? apply_filters( 'rtb_party_size_upper_limit', 100 ) : (int) $this->get_setting( 'party-size' );
|
720 |
|
721 |
-
for ( $i =
|
722 |
$options[$i] = $i;
|
723 |
}
|
724 |
|
90 |
$this->defaults = array(
|
91 |
|
92 |
'success-message' => _x( 'Thanks, your booking request is waiting to be confirmed. Updates will be sent to the email address you provided.', 'restaurant-reservations' ),
|
93 |
+
'date-format' => _x( 'mmmm d, yyyy', 'Default date format for display. Must match formatting rules at http://amsul.ca/pickadate.js/date/#formats', 'restaurant-reservations' ),
|
94 |
+
'time-format' => _x( 'h:i A', 'Default time format for display. Must match formatting rules at http://amsul.ca/pickadate.js/time/#formats', 'restaurant-reservations' ),
|
95 |
'time-interval' => _x( '30', 'Default interval in minutes when selecting a time.', 'restaurant-reservations' ),
|
96 |
|
97 |
// Email address where admin notifications should be sent
|
262 |
)
|
263 |
);
|
264 |
|
265 |
+
$sap->add_setting(
|
266 |
+
'rtb-settings',
|
267 |
+
'rtb-general',
|
268 |
+
'select',
|
269 |
+
array(
|
270 |
+
'id' => 'party-size-min',
|
271 |
+
'title' => __( 'Min Party Size', 'restaurant-reservations' ),
|
272 |
+
'description' => __( 'Set a minimum allowed party size for bookings.', 'restaurant-reservations' ),
|
273 |
+
'blank_option' => false,
|
274 |
+
'options' => $this->get_party_size_setting_options( false ),
|
275 |
+
)
|
276 |
+
);
|
277 |
+
|
278 |
$sap->add_setting(
|
279 |
'rtb-settings',
|
280 |
'rtb-general',
|
307 |
array(
|
308 |
'id' => 'date-format',
|
309 |
'title' => __( 'Date Format', 'restaurant-reservations' ),
|
310 |
+
'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/#formats">', '</a>', '<a href="' . admin_url( 'options-general.php' ) . '">', '</a>' ),
|
311 |
'placeholder' => $this->defaults['date-format'],
|
312 |
)
|
313 |
);
|
319 |
array(
|
320 |
'id' => 'time-format',
|
321 |
'title' => __( 'Time Format', 'restaurant-reservations' ),
|
322 |
+
'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/#formats">', '</a>', '<a href="' . admin_url( 'options-general.php' ) . '">', '</a>' ),
|
323 |
'placeholder' => $this->defaults['time-format'],
|
324 |
)
|
325 |
);
|
326 |
|
327 |
// Add i8n setting for pickadate if the frontend assets are to be loaded
|
328 |
+
if ( apply_filters( 'rtb-load-frontend-assets', true ) ) {
|
329 |
$sap->add_setting(
|
330 |
'rtb-settings',
|
331 |
'rtb-general',
|
339 |
);
|
340 |
}
|
341 |
|
342 |
+
$sap->add_setting(
|
343 |
+
'rtb-settings',
|
344 |
+
'rtb-general',
|
345 |
+
'textarea',
|
346 |
+
array(
|
347 |
+
'id' => 'ban-emails',
|
348 |
+
'title' => __( 'Banned Email Addresses', 'restaurant-reservations' ),
|
349 |
+
'description' => __( 'You can block bookings from specific email addresses. Enter each email address on a separate line.', 'restaurant-reservations' ),
|
350 |
+
)
|
351 |
+
);
|
352 |
+
|
353 |
+
$sap->add_setting(
|
354 |
+
'rtb-settings',
|
355 |
+
'rtb-general',
|
356 |
+
'textarea',
|
357 |
+
array(
|
358 |
+
'id' => 'ban-ips',
|
359 |
+
'title' => __( 'Banned IP Addresses', 'restaurant-reservations' ),
|
360 |
+
'description' => __( 'You can block bookings from specific IP addresses. Enter each IP address on a separate line. Be aware that many internet providers rotate their IP address assignments, so an IP address may accidentally refer to a different user. Also, if you block an IP address used by a public connection, such as cafe WIFI, a public library, or a university network, you may inadvertantly block several people.', 'restaurant-reservations' ),
|
361 |
+
)
|
362 |
+
);
|
363 |
+
|
364 |
$sap->add_section(
|
365 |
'rtb-settings',
|
366 |
array(
|
469 |
'description' => __( 'Select how late customers can make their booking. (Administrators and Booking Managers are not restricted by this setting.)', 'restaurant-reservations' ),
|
470 |
'blank_option' => false,
|
471 |
'options' => array(
|
472 |
+
'' => __( 'Up to the last minute', 'restaurant-reservations' ),
|
473 |
+
'15' => __( 'At least 15 minutes in advance', 'restaurant-reservations' ),
|
474 |
+
'30' => __( 'At least 30 minutes in advance', 'restaurant-reservations' ),
|
475 |
+
'45' => __( 'At least 45 minutes in advance', 'restaurant-reservations' ),
|
476 |
+
'60' => __( 'At least 1 hour in advance', 'restaurant-reservations' ),
|
477 |
+
'240' => __( 'At least 4 hours in advance', 'restaurant-reservations' ),
|
478 |
+
'1440' => __( 'At least 24 hours in advance', 'restaurant-reservations' ),
|
479 |
+
'same_day' => __( 'Block same-day bookings', 'restaurant-reservations' ),
|
480 |
)
|
481 |
)
|
482 |
);
|
729 |
* Get options for the party size setting
|
730 |
* @since 1.3
|
731 |
*/
|
732 |
+
public function get_party_size_setting_options( $max = true ) {
|
733 |
|
734 |
+
$options = array();
|
735 |
+
|
736 |
+
if ( $max ) {
|
737 |
+
$options[''] = __( 'Any size', 'restaurant-reservations' );
|
738 |
+
}
|
739 |
|
740 |
$max = apply_filters( 'rtb_party_size_upper_limit', 100 );
|
741 |
|
753 |
public function get_form_party_options() {
|
754 |
|
755 |
$party_size = (int) $this->get_setting( 'party-size' );
|
756 |
+
$party_size_min = (int) $this->get_setting( 'party-size-min' );
|
757 |
|
758 |
+
$min = empty( $party_size_min ) ? 1 : (int) $this->get_setting( 'party-size-min' );
|
759 |
$max = empty( $party_size ) ? apply_filters( 'rtb_party_size_upper_limit', 100 ) : (int) $this->get_setting( 'party-size' );
|
760 |
|
761 |
+
for ( $i = $min; $i <= $max; $i++ ) {
|
762 |
$options[$i] = $i;
|
763 |
}
|
764 |
|
includes/WP_List_Table.BookingsTable.class.php
CHANGED
@@ -323,6 +323,7 @@ class rtbBookingsTable extends WP_List_Table {
|
|
323 |
}
|
324 |
|
325 |
$all_default_columns = $this->get_all_default_columns();
|
|
|
326 |
|
327 |
global $rtb_controller;
|
328 |
$visible_columns = $rtb_controller->settings->get_setting( 'bookings-table-columns' );
|
@@ -333,9 +334,9 @@ class rtbBookingsTable extends WP_List_Table {
|
|
333 |
$columns['cb'] = $all_default_columns['cb'];
|
334 |
$columns['date'] = $all_default_columns['date'];
|
335 |
|
336 |
-
foreach( $
|
337 |
if ( in_array( $key, $visible_columns ) ) {
|
338 |
-
$columns[$key] = $
|
339 |
}
|
340 |
}
|
341 |
$columns['details'] = $all_default_columns['details'];
|
@@ -374,6 +375,7 @@ class rtbBookingsTable extends WP_List_Table {
|
|
374 |
*/
|
375 |
public function get_all_columns() {
|
376 |
$columns = $this->get_all_default_columns();
|
|
|
377 |
return apply_filters( 'rtb_bookings_all_table_columns', $columns );
|
378 |
}
|
379 |
|
@@ -394,6 +396,7 @@ class rtbBookingsTable extends WP_List_Table {
|
|
394 |
* @since 0.0.1
|
395 |
*/
|
396 |
public function column_default( $booking, $column_name ) {
|
|
|
397 |
switch ( $column_name ) {
|
398 |
case 'date' :
|
399 |
$value = $booking->format_date( $booking->date );
|
@@ -407,21 +410,26 @@ class rtbBookingsTable extends WP_List_Table {
|
|
407 |
}
|
408 |
|
409 |
break;
|
|
|
410 |
case 'party' :
|
411 |
$value = $booking->party;
|
412 |
break;
|
|
|
413 |
case 'name' :
|
414 |
$value = $booking->name;
|
415 |
break;
|
|
|
416 |
case 'email' :
|
417 |
$value = $booking->email;
|
418 |
$value .= '<div class="actions">';
|
419 |
$value .= '<a href="#" data-id="' . esc_attr( $booking->ID ) . '" data-action="email" data-email="' . esc_attr( $booking->email ) . '" data-name="' . $booking->name . '">' . __( 'Send Email', 'restaurant-reservations' ) . '</a>';
|
420 |
$value .= '</div>';
|
421 |
break;
|
|
|
422 |
case 'phone' :
|
423 |
$value = $booking->phone;
|
424 |
break;
|
|
|
425 |
case 'status' :
|
426 |
global $rtb_controller;
|
427 |
if ( !empty( $rtb_controller->cpts->booking_statuses[$booking->post_status] ) ) {
|
@@ -432,6 +440,7 @@ class rtbBookingsTable extends WP_List_Table {
|
|
432 |
$value = $booking->post_status;
|
433 |
}
|
434 |
break;
|
|
|
435 |
case 'details' :
|
436 |
$value = '';
|
437 |
|
@@ -454,6 +463,18 @@ class rtbBookingsTable extends WP_List_Table {
|
|
454 |
$value .= '</ul></div>';
|
455 |
}
|
456 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
457 |
default:
|
458 |
$value = isset( $booking->$column_name ) ? $booking->$column_name : '';
|
459 |
break;
|
@@ -485,29 +506,22 @@ class rtbBookingsTable extends WP_List_Table {
|
|
485 |
*/
|
486 |
public function add_details_column_items( $details, $booking ) {
|
487 |
global $rtb_controller;
|
488 |
-
$visible_columns = $this->
|
489 |
-
$
|
490 |
-
|
491 |
-
$detail_columns = array_diff( $visible_columns, $default_columns );
|
492 |
|
493 |
-
|
494 |
-
unset( $default_columns['cb'] );
|
495 |
-
unset( $default_columns['details'] );
|
496 |
-
unset( $default_columns['date'] );
|
497 |
|
498 |
-
|
499 |
-
foreach( $detail_columns as $key => $label ) {
|
500 |
-
|
501 |
-
$value = $this->column_default( $booking, $key );
|
502 |
-
if ( empty( $value ) ) {
|
503 |
-
continue;
|
504 |
-
}
|
505 |
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
);
|
510 |
}
|
|
|
|
|
|
|
|
|
|
|
511 |
}
|
512 |
|
513 |
return $details;
|
@@ -887,6 +901,12 @@ class rtbBookingsTable extends WP_List_Table {
|
|
887 |
$query = new rtbQuery( $args, 'bookings-table' );
|
888 |
$query->parse_request_args();
|
889 |
$query->prepare_args();
|
|
|
|
|
|
|
|
|
|
|
|
|
890 |
$query->args = apply_filters( 'rtb_bookings_table_query_args', $query->args );
|
891 |
|
892 |
$this->bookings = $query->get_bookings();
|
323 |
}
|
324 |
|
325 |
$all_default_columns = $this->get_all_default_columns();
|
326 |
+
$all_columns = $this->get_all_columns();
|
327 |
|
328 |
global $rtb_controller;
|
329 |
$visible_columns = $rtb_controller->settings->get_setting( 'bookings-table-columns' );
|
334 |
$columns['cb'] = $all_default_columns['cb'];
|
335 |
$columns['date'] = $all_default_columns['date'];
|
336 |
|
337 |
+
foreach( $all_columns as $key => $column ) {
|
338 |
if ( in_array( $key, $visible_columns ) ) {
|
339 |
+
$columns[$key] = $all_columns[$key];
|
340 |
}
|
341 |
}
|
342 |
$columns['details'] = $all_default_columns['details'];
|
375 |
*/
|
376 |
public function get_all_columns() {
|
377 |
$columns = $this->get_all_default_columns();
|
378 |
+
$columns['submitted-by'] = __( 'Submitted By', 'restaurant-reservations' );
|
379 |
return apply_filters( 'rtb_bookings_all_table_columns', $columns );
|
380 |
}
|
381 |
|
396 |
* @since 0.0.1
|
397 |
*/
|
398 |
public function column_default( $booking, $column_name ) {
|
399 |
+
|
400 |
switch ( $column_name ) {
|
401 |
case 'date' :
|
402 |
$value = $booking->format_date( $booking->date );
|
410 |
}
|
411 |
|
412 |
break;
|
413 |
+
|
414 |
case 'party' :
|
415 |
$value = $booking->party;
|
416 |
break;
|
417 |
+
|
418 |
case 'name' :
|
419 |
$value = $booking->name;
|
420 |
break;
|
421 |
+
|
422 |
case 'email' :
|
423 |
$value = $booking->email;
|
424 |
$value .= '<div class="actions">';
|
425 |
$value .= '<a href="#" data-id="' . esc_attr( $booking->ID ) . '" data-action="email" data-email="' . esc_attr( $booking->email ) . '" data-name="' . $booking->name . '">' . __( 'Send Email', 'restaurant-reservations' ) . '</a>';
|
426 |
$value .= '</div>';
|
427 |
break;
|
428 |
+
|
429 |
case 'phone' :
|
430 |
$value = $booking->phone;
|
431 |
break;
|
432 |
+
|
433 |
case 'status' :
|
434 |
global $rtb_controller;
|
435 |
if ( !empty( $rtb_controller->cpts->booking_statuses[$booking->post_status] ) ) {
|
440 |
$value = $booking->post_status;
|
441 |
}
|
442 |
break;
|
443 |
+
|
444 |
case 'details' :
|
445 |
$value = '';
|
446 |
|
463 |
$value .= '</ul></div>';
|
464 |
}
|
465 |
break;
|
466 |
+
|
467 |
+
case 'submitted-by' :
|
468 |
+
$ip = !empty( $booking->ip ) ? $booking->ip : __( 'Unknown IP', 'restaurant-reservations' );
|
469 |
+
$date_submission = isset( $booking->date_submission ) ? $booking->format_date( $booking->date_submission ) : __( 'Unknown Date', 'restaurant-reservations' );
|
470 |
+
$value = sprintf( esc_html__( 'Request from %s on %s.', 'restaurant-reservations' ), $ip, $date_submission );
|
471 |
+
$value .= '<div class="actions">';
|
472 |
+
$value .= '<a href="#" data-action="ban" data-email="' . esc_attr( $booking->email ) . '" data-id="' . absint( $booking->ID ) . '" data-ip="' . $ip . '">';
|
473 |
+
$value .= __( 'Ban Customer', 'restaurant-reservations' );
|
474 |
+
$value .= '</a>';
|
475 |
+
$value .= '</div>';
|
476 |
+
break;
|
477 |
+
|
478 |
default:
|
479 |
$value = isset( $booking->$column_name ) ? $booking->$column_name : '';
|
480 |
break;
|
506 |
*/
|
507 |
public function add_details_column_items( $details, $booking ) {
|
508 |
global $rtb_controller;
|
509 |
+
$visible_columns = $this->get_columns();
|
510 |
+
$all_columns = $this->get_all_columns();
|
|
|
|
|
511 |
|
512 |
+
$detail_columns = array_diff( $all_columns, $visible_columns );
|
|
|
|
|
|
|
513 |
|
514 |
+
foreach( $detail_columns as $key => $label ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
515 |
|
516 |
+
$value = $this->column_default( $booking, $key );
|
517 |
+
if ( empty( $value ) ) {
|
518 |
+
continue;
|
|
|
519 |
}
|
520 |
+
|
521 |
+
$details[] = array(
|
522 |
+
'label' => $label,
|
523 |
+
'value' => $value,
|
524 |
+
);
|
525 |
}
|
526 |
|
527 |
return $details;
|
901 |
$query = new rtbQuery( $args, 'bookings-table' );
|
902 |
$query->parse_request_args();
|
903 |
$query->prepare_args();
|
904 |
+
|
905 |
+
// Sort all bookings by newest first if no specific orderby is in play
|
906 |
+
if ( $query->args['date_range'] == 'all' && !isset( $_REQUEST['orderby'] ) ) {
|
907 |
+
$query->args['order'] = 'DESC';
|
908 |
+
}
|
909 |
+
|
910 |
$query->args = apply_filters( 'rtb_bookings_table_query_args', $query->args );
|
911 |
|
912 |
$this->bookings = $query->get_bookings();
|
includes/integrations/business-profile.php
CHANGED
@@ -14,7 +14,7 @@ function rtb_bp_maybe_enable_bp_locations( $post_type ) {
|
|
14 |
}
|
15 |
|
16 |
global $bpfwp_controller;
|
17 |
-
if ( isset( $bpfwp_controller ) && isset( $bpfwp_controller->cpts ) ) {
|
18 |
return $bpfwp_controller->cpts->location_cpt_slug;
|
19 |
}
|
20 |
|
14 |
}
|
15 |
|
16 |
global $bpfwp_controller;
|
17 |
+
if ( isset( $bpfwp_controller ) && isset( $bpfwp_controller->cpts ) && $bpfwp_controller->settings->get_setting( 'multiple-locations' ) ) {
|
18 |
return $bpfwp_controller->cpts->location_cpt_slug;
|
19 |
}
|
20 |
|
includes/template-functions.php
CHANGED
@@ -110,7 +110,11 @@ function rtb_print_booking_form( $args = array() ) {
|
|
110 |
<?php
|
111 |
foreach( $contents['fields'] as $slug => $field ) {
|
112 |
|
113 |
-
$args = empty( $field['callback_args'] ) ?
|
|
|
|
|
|
|
|
|
114 |
|
115 |
call_user_func( $field['callback'], $slug, $field['title'], $field['request_input'], $args );
|
116 |
}
|
@@ -172,17 +176,21 @@ function rtb_enqueue_assets() {
|
|
172 |
wp_localize_script(
|
173 |
'rtb-booking-form',
|
174 |
'rtb_pickadate',
|
175 |
-
|
176 |
-
'
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
|
|
|
|
|
|
|
|
186 |
)
|
187 |
);
|
188 |
|
@@ -191,7 +199,7 @@ function rtb_enqueue_assets() {
|
|
191 |
|
192 |
/**
|
193 |
* Get rules for datepicker date ranges
|
194 |
-
* See: http://amsul.ca/pickadate.js/date
|
195 |
* @since 0.0.1
|
196 |
*/
|
197 |
if ( !function_exists( 'rtb_get_datepicker_rules' ) ) {
|
@@ -269,6 +277,7 @@ function rtb_print_form_text_field( $slug, $title, $value, $args = array() ) {
|
|
269 |
$type = empty( $args['input_type'] ) ? 'text' : esc_attr( $args['input_type'] );
|
270 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
271 |
$classes[] = 'rtb-text';
|
|
|
272 |
|
273 |
?>
|
274 |
|
@@ -277,7 +286,7 @@ function rtb_print_form_text_field( $slug, $title, $value, $args = array() ) {
|
|
277 |
<label for="rtb-<?php echo $slug; ?>">
|
278 |
<?php echo $title; ?>
|
279 |
</label>
|
280 |
-
<input type="<?php echo $type; ?>" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="<?php echo $value;
|
281 |
</div>
|
282 |
|
283 |
<?php
|
@@ -297,6 +306,7 @@ function rtb_print_form_textarea_field( $slug, $title, $value, $args = array() )
|
|
297 |
$value = preg_replace('/\<br(\s*)?\/?\>/i', '', $value);
|
298 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
299 |
$classes[] = 'rtb-textarea';
|
|
|
300 |
|
301 |
?>
|
302 |
|
@@ -305,7 +315,7 @@ function rtb_print_form_textarea_field( $slug, $title, $value, $args = array() )
|
|
305 |
<label for="rtb-<?php echo $slug; ?>">
|
306 |
<?php echo $title; ?>
|
307 |
</label>
|
308 |
-
<textarea name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug;
|
309 |
</div>
|
310 |
|
311 |
<?php
|
@@ -325,6 +335,7 @@ function rtb_print_form_select_field( $slug, $title, $value, $args ) {
|
|
325 |
$options = is_array( $args['options'] ) ? $args['options'] : array();
|
326 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
327 |
$classes[] = 'rtb-select';
|
|
|
328 |
|
329 |
?>
|
330 |
|
@@ -333,7 +344,7 @@ function rtb_print_form_select_field( $slug, $title, $value, $args ) {
|
|
333 |
<label for="rtb-<?php echo $slug; ?>">
|
334 |
<?php echo $title; ?>
|
335 |
</label>
|
336 |
-
<select name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug;
|
337 |
<?php foreach ( $options as $opt_value => $opt_label ) : ?>
|
338 |
<option value="<?php echo esc_attr( $opt_value ); ?>" <?php selected( $opt_value, $value ); ?>><?php echo esc_attr( $opt_label ); ?></option>
|
339 |
<?php endforeach; ?>
|
@@ -348,7 +359,6 @@ function rtb_print_form_select_field( $slug, $title, $value, $args ) {
|
|
348 |
/**
|
349 |
* Print a checkbox form field
|
350 |
*
|
351 |
-
* @uses rtb_print_form_tick_field
|
352 |
* @since 1.3.1
|
353 |
*/
|
354 |
if ( !function_exists( 'rtb_print_form_checkbox_field' ) ) {
|
@@ -382,7 +392,6 @@ function rtb_print_form_checkbox_field( $slug, $title, $value, $args ) {
|
|
382 |
/**
|
383 |
* Print a radio button form field
|
384 |
*
|
385 |
-
* @uses rtb_print_form_tick_field
|
386 |
* @since 1.3.1
|
387 |
*/
|
388 |
if ( !function_exists( 'rtb_print_form_radio_field' ) ) {
|
@@ -393,6 +402,7 @@ function rtb_print_form_radio_field( $slug, $title, $value, $args ) {
|
|
393 |
$options = is_array( $args['options'] ) ? $args['options'] : array();
|
394 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
395 |
$classes[] = 'rtb-radio';
|
|
|
396 |
|
397 |
?>
|
398 |
|
@@ -403,7 +413,7 @@ function rtb_print_form_radio_field( $slug, $title, $value, $args ) {
|
|
403 |
</label>
|
404 |
<?php foreach ( $options as $opt_value => $opt_label ) : ?>
|
405 |
<label>
|
406 |
-
<input type="radio" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="<?php echo esc_attr( $opt_value ); ?>" <?php checked( $opt_value, $value ); ?>>
|
407 |
<?php echo $opt_label; ?>
|
408 |
</label>
|
409 |
<?php endforeach; ?>
|
@@ -425,13 +435,14 @@ function rtb_print_form_confirm_field( $slug, $title, $value, $args ) {
|
|
425 |
$value = esc_attr( $value );
|
426 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
427 |
$classes[] = 'rtb-confirm';
|
|
|
428 |
|
429 |
?>
|
430 |
|
431 |
<div <?php echo rtb_print_element_class( $slug, $classes ); ?>>
|
432 |
<?php echo rtb_print_form_error( $slug ); ?>
|
433 |
<label for="rtb-<?php echo $slug; ?>">
|
434 |
-
<input type="checkbox" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="1" <?php checked( $value, 1 ); ?>>
|
435 |
<?php echo $title; ?>
|
436 |
</label>
|
437 |
</div>
|
110 |
<?php
|
111 |
foreach( $contents['fields'] as $slug => $field ) {
|
112 |
|
113 |
+
$args = empty( $field['callback_args'] ) ? array() : $field['callback_args'];
|
114 |
+
|
115 |
+
if ( !empty( $field['required'] ) ) {
|
116 |
+
$args = array_merge( $args, array( 'required' => $field['required'] ) );
|
117 |
+
}
|
118 |
|
119 |
call_user_func( $field['callback'], $slug, $field['title'], $field['request_input'], $args );
|
120 |
}
|
176 |
wp_localize_script(
|
177 |
'rtb-booking-form',
|
178 |
'rtb_pickadate',
|
179 |
+
apply_filters(
|
180 |
+
'rtb_pickadate_args',
|
181 |
+
array(
|
182 |
+
'date_format' => $rtb_controller->settings->get_setting( 'date-format' ),
|
183 |
+
'time_format' => $rtb_controller->settings->get_setting( 'time-format' ),
|
184 |
+
'disable_dates' => rtb_get_datepicker_rules(),
|
185 |
+
'schedule_open' => $rtb_controller->settings->get_setting( 'schedule-open' ),
|
186 |
+
'schedule_closed' => $rtb_controller->settings->get_setting( 'schedule-closed' ),
|
187 |
+
'early_bookings' => is_admin() && current_user_can( 'manage_bookings' ) ? '' : $rtb_controller->settings->get_setting( 'early-bookings' ),
|
188 |
+
'late_bookings' => is_admin() && current_user_can( 'manage_bookings' ) ? '' : $rtb_controller->settings->get_setting( 'late-bookings' ),
|
189 |
+
'date_onload' => $rtb_controller->settings->get_setting( 'date-onload' ),
|
190 |
+
'time_interval' => $rtb_controller->settings->get_setting( 'time-interval' ),
|
191 |
+
'first_day' => $rtb_controller->settings->get_setting( 'week-start' ),
|
192 |
+
'allow_past' => is_admin() && current_user_can( 'manage_bookings' ),
|
193 |
+
)
|
194 |
)
|
195 |
);
|
196 |
|
199 |
|
200 |
/**
|
201 |
* Get rules for datepicker date ranges
|
202 |
+
* See: http://amsul.ca/pickadate.js/date/#disable-dates
|
203 |
* @since 0.0.1
|
204 |
*/
|
205 |
if ( !function_exists( 'rtb_get_datepicker_rules' ) ) {
|
277 |
$type = empty( $args['input_type'] ) ? 'text' : esc_attr( $args['input_type'] );
|
278 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
279 |
$classes[] = 'rtb-text';
|
280 |
+
$required = isset( $args['required'] ) && $args['required'] ? ' required aria-required="true"' : '';
|
281 |
|
282 |
?>
|
283 |
|
286 |
<label for="rtb-<?php echo $slug; ?>">
|
287 |
<?php echo $title; ?>
|
288 |
</label>
|
289 |
+
<input type="<?php echo $type; ?>" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="<?php echo $value; ?>"<?php echo $required; ?>>
|
290 |
</div>
|
291 |
|
292 |
<?php
|
306 |
$value = preg_replace('/\<br(\s*)?\/?\>/i', '', $value);
|
307 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
308 |
$classes[] = 'rtb-textarea';
|
309 |
+
$required = isset( $args['required'] ) && $args['required'] ? ' required aria-required="true"' : '';
|
310 |
|
311 |
?>
|
312 |
|
315 |
<label for="rtb-<?php echo $slug; ?>">
|
316 |
<?php echo $title; ?>
|
317 |
</label>
|
318 |
+
<textarea name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>"<?php echo $required; ?>><?php echo $value; ?></textarea>
|
319 |
</div>
|
320 |
|
321 |
<?php
|
335 |
$options = is_array( $args['options'] ) ? $args['options'] : array();
|
336 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
337 |
$classes[] = 'rtb-select';
|
338 |
+
$required = isset( $args['required'] ) && $args['required'] ? ' required aria-required="true"' : '';
|
339 |
|
340 |
?>
|
341 |
|
344 |
<label for="rtb-<?php echo $slug; ?>">
|
345 |
<?php echo $title; ?>
|
346 |
</label>
|
347 |
+
<select name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>"<?php echo $required; ?>>
|
348 |
<?php foreach ( $options as $opt_value => $opt_label ) : ?>
|
349 |
<option value="<?php echo esc_attr( $opt_value ); ?>" <?php selected( $opt_value, $value ); ?>><?php echo esc_attr( $opt_label ); ?></option>
|
350 |
<?php endforeach; ?>
|
359 |
/**
|
360 |
* Print a checkbox form field
|
361 |
*
|
|
|
362 |
* @since 1.3.1
|
363 |
*/
|
364 |
if ( !function_exists( 'rtb_print_form_checkbox_field' ) ) {
|
392 |
/**
|
393 |
* Print a radio button form field
|
394 |
*
|
|
|
395 |
* @since 1.3.1
|
396 |
*/
|
397 |
if ( !function_exists( 'rtb_print_form_radio_field' ) ) {
|
402 |
$options = is_array( $args['options'] ) ? $args['options'] : array();
|
403 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
404 |
$classes[] = 'rtb-radio';
|
405 |
+
$required = isset( $args['required'] ) && $args['required'] ? ' required aria-required="true"' : '';
|
406 |
|
407 |
?>
|
408 |
|
413 |
</label>
|
414 |
<?php foreach ( $options as $opt_value => $opt_label ) : ?>
|
415 |
<label>
|
416 |
+
<input type="radio" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="<?php echo esc_attr( $opt_value ); ?>" <?php checked( $opt_value, $value ); ?><?php echo $required; ?>>
|
417 |
<?php echo $opt_label; ?>
|
418 |
</label>
|
419 |
<?php endforeach; ?>
|
435 |
$value = esc_attr( $value );
|
436 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
437 |
$classes[] = 'rtb-confirm';
|
438 |
+
$required = isset( $args['required'] ) && $args['required'] ? ' required aria-required="true"' : '';
|
439 |
|
440 |
?>
|
441 |
|
442 |
<div <?php echo rtb_print_element_class( $slug, $classes ); ?>>
|
443 |
<?php echo rtb_print_form_error( $slug ); ?>
|
444 |
<label for="rtb-<?php echo $slug; ?>">
|
445 |
+
<input type="checkbox" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="1" <?php checked( $value, 1 ); ?><?php echo $required; ?>>
|
446 |
<?php echo $title; ?>
|
447 |
</label>
|
448 |
</div>
|
languages/restaurant-reservations.pot
CHANGED
@@ -1,231 +1,230 @@
|
|
1 |
-
# Copyright (C) 2016
|
2 |
-
# This file is distributed under the
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: Restaurant Reservations 1.
|
6 |
-
"Report-Msgid-Bugs-To: "
|
7 |
-
"
|
8 |
-
"POT-Creation-Date: 2016-06-20 07:16:22+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: 2016-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
|
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:101
|
29 |
-
#: includes/WP_List_Table.BookingsTable.class.php:400
|
30 |
-
msgid "Loading"
|
31 |
-
msgstr ""
|
32 |
|
33 |
-
#: includes/Addons.class.php:
|
34 |
msgid "Addons for Restaurant Reservations"
|
35 |
msgstr ""
|
36 |
|
37 |
-
#: includes/
|
38 |
-
msgid "You have been logged out. Please login again to retrieve the addons."
|
39 |
-
msgstr ""
|
40 |
-
|
41 |
-
#: includes/Addons.class.php:176
|
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:204
|
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:84
|
56 |
msgid "Restaurant Bookings"
|
57 |
msgstr ""
|
58 |
|
59 |
-
#: includes/AdminBookings.class.php:
|
60 |
msgid "Add New"
|
61 |
msgstr ""
|
62 |
|
63 |
-
#: includes/AdminBookings.class.php:
|
64 |
msgid "Columns"
|
65 |
msgstr ""
|
66 |
|
67 |
-
#: includes/AdminBookings.class.php:
|
68 |
msgid "Add Booking"
|
69 |
msgstr ""
|
70 |
|
71 |
-
#: includes/AdminBookings.class.php:
|
72 |
-
#: includes/AdminBookings.class.php:
|
73 |
msgid "Cancel"
|
74 |
msgstr ""
|
75 |
|
76 |
-
#: includes/AdminBookings.class.php:
|
77 |
-
#: includes/WP_List_Table.BookingsTable.class.php:
|
78 |
msgid "Send Email"
|
79 |
msgstr ""
|
80 |
|
81 |
-
#: includes/AdminBookings.class.php:
|
82 |
msgid "Subject"
|
83 |
msgstr ""
|
84 |
|
85 |
-
#: includes/AdminBookings.class.php:
|
86 |
-
#: includes/WP_List_Table.BookingsTable.class.php:
|
87 |
msgid "Message"
|
88 |
msgstr ""
|
89 |
|
90 |
-
#: includes/AdminBookings.class.php:
|
91 |
msgid "Update"
|
92 |
msgstr ""
|
93 |
|
94 |
-
#: includes/AdminBookings.class.php:
|
|
|
95 |
msgid "Close"
|
96 |
msgstr ""
|
97 |
|
98 |
-
#: includes/AdminBookings.class.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
msgid "Booking Status"
|
100 |
msgstr ""
|
101 |
|
102 |
-
#: includes/AdminBookings.class.php:
|
103 |
msgid "Send notifications"
|
104 |
msgstr ""
|
105 |
|
106 |
-
#: includes/AdminBookings.class.php:
|
107 |
msgid "Learn more"
|
108 |
msgstr ""
|
109 |
|
110 |
-
#: includes/AdminBookings.class.php:
|
111 |
msgid ""
|
112 |
"When adding a booking or changing a booking's status with this form, no "
|
113 |
"email notifications will be sent. Check this option if you want to send "
|
114 |
"email notifications."
|
115 |
msgstr ""
|
116 |
|
117 |
-
#: includes/AdminBookings.class.php:
|
118 |
msgid "You have been logged out. Please %slogin again%s."
|
119 |
msgstr ""
|
120 |
|
121 |
-
#: includes/AdminBookings.class.php:
|
122 |
msgid ""
|
123 |
"This booking has been sent to the %sTrash%s where it can not be edited. Set "
|
124 |
"the booking to Pending or Confirmed to edit it."
|
125 |
msgstr ""
|
126 |
|
127 |
-
#: includes/AdminBookings.class.php:
|
128 |
msgid "The booking could not be retrieved. Please reload the page and try again."
|
129 |
msgstr ""
|
130 |
|
131 |
-
#: includes/AdminBookings.class.php:
|
132 |
msgid ""
|
133 |
"Unable to trash this post. Please try again. If you continue to have "
|
134 |
"trouble, please refresh the page."
|
135 |
msgstr ""
|
136 |
|
137 |
-
#: includes/AdminBookings.class.php:
|
138 |
msgid "Please enter a message before sending the email."
|
139 |
msgstr ""
|
140 |
|
141 |
-
#: includes/AdminBookings.class.php:
|
142 |
msgid "The email could not be sent because some critical information was missing."
|
143 |
msgstr ""
|
144 |
|
145 |
-
#: includes/AdminBookings.class.php:
|
146 |
msgid "There was an error loading the booking and the email was not sent."
|
147 |
msgstr ""
|
148 |
|
149 |
-
#: includes/AdminBookings.class.php:
|
150 |
msgid "You must select at least one column to display."
|
151 |
msgstr ""
|
152 |
|
|
|
|
|
|
|
|