Restaurant Reservations - Version 1.2.2

Version Description

This update adds support for a new MailChimp addon that will be released soon. An addons page is now available under the Bookings menu. A bug in which custom date/time formats could cause validation errors has been fixed. New hooks are now in place so that it's easier to customize the form output.

Download this release

Release Info

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

Code changes from version 1.2.1 to 1.2.2

Files changed (30) hide show
  1. assets/css/admin.css +81 -0
  2. assets/css/booking-form.css +9 -0
  3. assets/js/admin.js +112 -0
  4. assets/js/booking-form.js +19 -5
  5. includes/Addons.class.php +197 -0
  6. includes/Settings.class.php +1 -1
  7. includes/template-functions.php +158 -61
  8. lib/simple-admin-pages/README.md +2 -2
  9. lib/simple-admin-pages/classes/AdminPage.Menu.class.php +1 -1
  10. lib/simple-admin-pages/classes/AdminPage.Submenu.class.php +1 -1
  11. lib/simple-admin-pages/classes/AdminPage.Themes.class.php +1 -1
  12. lib/simple-admin-pages/classes/AdminPage.class.php +1 -1
  13. lib/simple-admin-pages/classes/AdminPageSection.class.php +1 -1
  14. lib/simple-admin-pages/classes/AdminPageSetting.Address.class.php +138 -0
  15. lib/simple-admin-pages/classes/AdminPageSetting.Editor.class.php +1 -1
  16. lib/simple-admin-pages/classes/AdminPageSetting.HTML.class.php +1 -1
  17. lib/simple-admin-pages/classes/AdminPageSetting.OpeningHours.class.php +1 -1
  18. lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php +1 -1
  19. lib/simple-admin-pages/classes/AdminPageSetting.Select.class.php +1 -1
  20. lib/simple-admin-pages/classes/AdminPageSetting.SelectPost.class.php +1 -1
  21. lib/simple-admin-pages/classes/AdminPageSetting.SelectTaxonomy.class.php +1 -1
  22. lib/simple-admin-pages/classes/AdminPageSetting.Text.class.php +1 -1
  23. lib/simple-admin-pages/classes/AdminPageSetting.Textarea.class.php +1 -1
  24. lib/simple-admin-pages/classes/AdminPageSetting.Toggle.class.php +1 -1
  25. lib/simple-admin-pages/classes/AdminPageSetting.class.php +1 -1
  26. lib/simple-admin-pages/classes/Library.class.php +29 -17
  27. lib/simple-admin-pages/js/address.js +96 -0
  28. lib/simple-admin-pages/js/scheduler.js +56 -13
  29. readme.txt +14 -4
  30. restaurant-reservations.php +12 -3
assets/css/admin.css CHANGED
@@ -89,3 +89,84 @@
89
min-width: 8em;
90
display: inline-block;
91
}
89
min-width: 8em;
90
display: inline-block;
91
}
92
+
93
+ /* Addons Page */
94
+ #rtb-addons {
95
+ margin-top: 2em;
96
+ }
97
+
98
+ #rtb-addons .rtb-loading {
99
+ line-height: 10em;
100
+ font-size: 2em;
101
+ text-align: center;
102
+ text-transform: uppercase;
103
+ font-weight: bold;
104
+ background: #eee;
105
+ background: rgba(0,0,0,0.1);
106
+ color: #777;
107
+ color: rgba(0,0,0,0.54);
108
+ }
109
+
110
+ #rtb-addons .rtb-loading .spinner {
111
+ float: none;
112
+ display: inline-block;
113
+ }
114
+
115
+ #rtb-addons .error {
116
+ padding: 0.25em 0.5em;
117
+ background: #f50;
118
+ color: #fff;
119
+ }
120
+
121
+ #rtb-addons .error a {
122
+ color: #fff;
123
+ }
124
+
125
+ #rtb-addons .addon {
126
+ margin-bottom: 20px;
127
+ padding: 20px;
128
+ background: #fff;
129
+ min-height: 128px;
130
+ border-radius: 3px;
131
+ display: none;
132
+ }
133
+
134
+ #rtb-addons img {
135
+ float: left;
136
+ width: 128px;
137
+ height: 128px;
138
+ margin: 0 20px 20px 0;
139
+ }
140
+
141
+ #rtb-addons .action {
142
+ margin-top: 2em;
143
+ }
144
+
145
+ #rtb-addons .soon,
146
+ #rtb-addons .installed {
147
+ line-height: 28px;
148
+ display: inline-block;
149
+ padding: 0 0.75em;
150
+ border-radius: 3px;
151
+ box-shadow: 0 1px 0 #ccc;
152
+ }
153
+
154
+ #rtb-addons .soon {
155
+ background: #F0F05E;
156
+ }
157
+
158
+ #rtb-addons .installed {
159
+ background: #81F05E;
160
+ }
161
+
162
+ @media screen and (max-width: 600px) {
163
+
164
+ #rtb-addons .addon {
165
+ text-align: center;
166
+ }
167
+
168
+ #rtb-addons img {
169
+ float: none;
170
+ margin: 0;
171
+ }
172
+ }
assets/css/booking-form.css CHANGED
@@ -10,6 +10,9 @@
10
.rtb-booking-form fieldset>div {
11
margin-top: 1em;
12
}
13
.rtb-booking-form label {
14
display: block;
15
}
@@ -17,6 +20,12 @@
17
width: 100%;
18
max-width: 15em;
19
}
20
.rtb-booking-form textarea {
21
width: 100%;
22
max-width: 30em;
10
.rtb-booking-form fieldset>div {
11
margin-top: 1em;
12
}
13
+ .rtb-booking-form fieldset>div:first-child {
14
+ margin-top: 0;
15
+ }
16
.rtb-booking-form label {
17
display: block;
18
}
20
width: 100%;
21
max-width: 15em;
22
}
23
+ .rtb-booking-form input[type="checkbox"],
24
+ .rtb-booking-form input[type="radio"] {
25
+ width: auto;
26
+ margin-right: 0.25em;
27
+ vertical-align: middle;
28
+ }
29
.rtb-booking-form textarea {
30
width: 100%;
31
max-width: 30em;
assets/js/admin.js CHANGED
@@ -19,4 +19,116 @@ jQuery(document).ready(function ($) {
19
return false;
20
});
21
22
});
19
return false;
20
});
21
22
+ // Show the addons
23
+ if ( $( '#rtb-addons' ).length ) {
24
+
25
+ var rtbAddons = {
26
+
27
+ el: $( '#rtb-addons' ),
28
+
29
+ load: function() {
30
+
31
+ var params = {
32
+ action: 'rtb-addons',
33
+ nonce: rtb_addons.nonce
34
+ };
35
+
36
+ var data = $.param( params );
37
+
38
+ // Send Ajax request
39
+ var jqxhr = $.post( ajaxurl, data, function( r ) {
40
+
41
+ rtbAddons.el.find( '.rtb-loading' ).fadeOut( '250', function() {
42
+ if ( r.success ) {
43
+ rtbAddons.showAddons( r );
44
+ } else {
45
+ rtbAddons.showError( r );
46
+ }
47
+ });
48
+
49
+
50
+ });
51
+ },
52
+
53
+ showAddons: function( r ) {
54
+
55
+ if ( typeof r.data == 'undefined' || !r.data.length ) {
56
+ rtbAddons.showError();
57
+ return false;
58
+ }
59
+
60
+ for( var i in r.data ) {
61
+ rtbAddons.el.append( rtbAddons.getAddonHTML( r.data[i] ) );
62
+ rtbAddons.el.find( '.addon.' + r.data[i].id ).fadeIn();
63
+ }
64
+ },
65
+
66
+ showError: function( r ) {
67
+
68
+ if ( typeof r.data == 'undefined' || typeof r.data.msg == 'undefined' ) {
69
+ rtbAddons.el.html( '<span class="error">' + rtb_addons.strings.error_unknown + '</span>' );
70
+ } else {
71
+ rtbAddons.el.html( '<span class="error">' + r.data.msg + '</span>' );
72
+ }
73
+
74
+ },
75
+
76
+ getAddonHTML: function( addon ) {
77
+
78
+ if ( typeof addon.id === 'undefined' && typeof addon.title === 'undefined' ) {
79
+ return;
80
+ }
81
+
82
+ var html = '<div class="addon ' + addon.id + '">';
83
+
84
+ if ( typeof addon.url !== 'undefined' && typeof addon.img !== 'undefined' ) {
85
+ html += '<a href="' + addon.url + '"><img src="' + addon.img + '"></a>';
86
+ } else if ( typeof addon.img !== 'undefind' ) {
87
+ html += '<img src="' + addon.img + '">';
88
+ }
89
+
90
+ html += '<h3>' + addon.title + '</h3>';
91
+
92
+ html += '<div class="details">';
93
+
94
+ if ( typeof addon.description !== 'undefined' ) {
95
+ html += '<div class="description">' + addon.description + '</div>';
96
+ }
97
+
98
+ if ( typeof addon.status !== 'undefined' ) {
99
+
100
+ html += '<div class="action">';
101
+
102
+ if ( addon.status === 'released' && typeof addon.url !== 'undefined' ) {
103
+ html += '<a href="' + addon.url + '" class="button button-primary" target="_blank">';
104
+
105
+ if ( typeof addon.price !== 'undefined' && addon.price.length ) {
106
+ html += rtb_addons.strings.learn_more;
107
+ } else {
108
+ html += rtb_addons.strings.free;
109
+ }
110
+
111
+ html += '</a>';
112
+
113
+ } else if ( addon.status === 'installed' ) {
114
+ html += '<span class="installed">' + rtb_addons.strings.installed + '</span>';
115
+
116
+ } else {
117
+ html += '<span class="soon">' + rtb_addons.strings.coming_soon + '</span>';
118
+ }
119
+
120
+ html += '</div>'; // .action
121
+ }
122
+
123
+ html += '</div>'; // .details
124
+
125
+ html += '</div>'; // .addon
126
+
127
+ return html;
128
+ }
129
+ };
130
+
131
+ rtbAddons.load();
132
+ }
133
+
134
});
assets/js/booking-form.js CHANGED
@@ -26,7 +26,7 @@ jQuery(document).ready(function ($) {
26
if ( typeof rtb_pickadate !== 'undefined' ) {
27
28
// Declare datepicker
29
- var $date_input = $( '#rtb-date' ).pickadate({
30
format: rtb_pickadate.date_format,
31
formatSubmit: 'yyyy/mm/dd',
32
hiddenName: true,
@@ -45,13 +45,27 @@ jQuery(document).ready(function ($) {
45
});
46
47
// Declare timepicker
48
- var $time_input = $( '#rtb-time' ).pickatime({
49
format: rtb_pickadate.time_format,
50
- interval: parseInt( rtb_pickadate.time_interval, 10 )
51
});
52
53
- var datepicker = $date_input.pickadate( 'picker' );
54
- var timepicker = $time_input.pickatime( 'picker' );
55
56
if ( typeof datepicker == 'undefined' ) {
57
return;
26
if ( typeof rtb_pickadate !== 'undefined' ) {
27
28
// Declare datepicker
29
+ var date_input = $( '#rtb-date' ).pickadate({
30
format: rtb_pickadate.date_format,
31
formatSubmit: 'yyyy/mm/dd',
32
hiddenName: true,
45
});
46
47
// Declare timepicker
48
+ var time_input = $( '#rtb-time' ).pickatime({
49
format: rtb_pickadate.time_format,
50
+ formatSubmit: 'h:i A',
51
+ hiddenName: true,
52
+ interval: parseInt( rtb_pickadate.time_interval, 10 ),
53
+
54
+ // Select the value when loaded if a value has been set
55
+ onStart: function() {
56
+ if ( $( '#rtb-time' ).val() !== '' ) {
57
+ var today = new Date();
58
+ var today_date = today.getFullYear() + '/' + ( today.getMonth() + 1 ) + '/' + today.getDate();
59
+ var time = new Date( today_date + ' ' + $( '#rtb-time' ).val() );
60
+ if ( Object.prototype.toString.call( time ) === "[object Date]" ) {
61
+ this.set( 'select', time );
62
+ }
63
+ }
64
+ }
65
});
66
67
+ var datepicker = date_input.pickadate( 'picker' );
68
+ var timepicker = time_input.pickatime( 'picker' );
69
70
if ( typeof datepicker == 'undefined' ) {
71
return;
includes/Addons.class.php ADDED
@@ -0,0 +1,197 @@
1
+ <?php
2
+ if ( !defined( 'ABSPATH' ) ) exit;
3
+
4
+ if ( !class_exists( 'rtbAddons' ) ) {
5
+ /**
6
+ * Class to handle the addons page for Restaurant Reservations
7
+ *
8
+ * @since 1.3
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
+ * Parse the arguments passed in the construction and assign them to
43
+ * internal variables.
44
+ */
45
+ private function parse_args( $args ) {
46
+ foreach ( $args as $key => $val ) {
47
+ switch ( $key ) {
48
+
49
+ case 'api_url' :
50
+ $this->{$key} = esc_url( $val );
51
+
52
+ case 'plugin' :
53
+ $this->{$key} = esc_attr( $val );
54
+
55
+ default :
56
+ $this->{$key} = $val;
57
+
58
+ }
59
+ }
60
+
61
+ do_action( $this->plugin . '_addons_parse_args' );
62
+ }
63
+
64
+ /**
65
+ * Check that we have everything we need to render the addons page
66
+ */
67
+ public function check_config() {
68
+
69
+ if ( !empty( $this->api_url ) && !empty( $this->plugin ) ) {
70
+ return true;
71
+ }
72
+
73
+ return false;
74
+ }
75
+
76
+ /**
77
+ * Send addon data to the javascript
78
+ */
79
+ public function enqueue_admin_assets() {
80
+
81
+ $screen = get_current_screen();
82
+ if ( $screen->base == 'bookings_page_rtb-addons' ) {
83
+ wp_localize_script(
84
+ 'rtb-admin',
85
+ 'rtb_addons',
86
+ array(
87
+ 'nonce' => wp_create_nonce( 'rtb-addons' ),
88
+ 'strings' => array(
89
+ 'loading' => __( 'Loading', RTB_TEXTDOMAIN ),
90
+ 'error_unknown' => _x( 'An unknown error occured.', 'Error message when retrieving list of addons', RTB_TEXTDOMAIN ),
91
+ 'installed' => _x( 'Already Installed', 'Label for an addon that is already installed and activated.', RTB_TEXTDOMAIN ),
92
+ 'coming_soon' => _x( 'Coming Soon', 'Label for an addon that is not yet released.', RTB_TEXTDOMAIN ),
93
+ 'free' => _x( 'Free', 'Label for an addon that is free.', RTB_TEXTDOMAIN ),
94
+ 'learn_more' => _x( 'Get It', 'Label for an addon that is released.', RTB_TEXTDOMAIN ),
95
+ )
96
+ )
97
+ );
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Add the addons page to the admin menu
103
+ */
104
+ public function add_menu_page() {
105
+
106
+ add_submenu_page(
107
+ 'rtb-bookings',
108
+ _x( 'Addons', 'Title of addons page', RTB_TEXTDOMAIN ),
109
+ _x( 'Addons', 'Title of addons page in the admin menu', RTB_TEXTDOMAIN ),
110
+ 'manage_options',
111
+ 'rtb-addons',
112
+ array( $this, 'show_admin_addons_page' )
113
+ );
114
+
115
+ }
116
+
117
+ /**
118
+ * Display the addons page
119
+ */
120
+ public function show_admin_addons_page() {
121
+
122
+ // @todo check for transient and only call the api if its missing
123
+ ?>
124
+
125
+ <div class="wrap">
126
+ <h2><?php _e( 'Addons for Restaurant Reservations', RTB_TEXTDOMAIN ); ?></h2>
127
+ <?php do_action( 'rtb_addons_pre' ); ?>
128
+ <div id="rtb-addons">
129
+ <div class="rtb-loading">
130
+ <div class="spinner"></div>
131
+ Loading
132
+ </div>
133
+ </div>
134
+ <?php do_action( 'rtb_addons_post' ); ?>
135
+ </div>
136
+
137
+ <?php
138
+ }
139
+
140
+ /**
141
+ * Handle ajax request for addons from logged out user
142
+ */
143
+ public function ajax_nopriv_get_addons() {
144
+
145
+ wp_send_json_error(
146
+ array(
147
+ 'error' => 'loggedout',
148
+ 'msg' => __( 'You have been logged out. Please login again to retrieve the addons.', RTB_TEXTDOMAIN ),
149
+ )
150
+ );
151
+ }
152
+
153
+ /**
154
+ * Handle ajax request for addons
155
+ */
156
+ public function ajax_get_addons() {
157
+
158
+ $url = $this->api_url . $this->plugin;
159
+
160
+ if ( !check_ajax_referer( 'rtb-addons', 'nonce' ) || !current_user_can( 'manage_options' )) {
161
+ wp_send_json_error(
162
+ array(
163
+ 'error' => 'nopriv',
164
+ 'msg' => __( 'You do not have permission to access this page. Please login to an administrator account if you have one.', RTB_TEXTDOMAIN ),
165
+ )
166
+ );
167
+ }
168
+
169
+ if ( function_exists( 'curl_init' ) && function_exists( 'curl_setop' ) ) {
170
+ $ch = curl_init();
171
+ curl_setopt( $ch, CURLOPT_URL, $url );
172
+ curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' ) );
173
+ curl_setopt( $ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0' );
174
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
175
+ curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );
176
+ $result = curl_exec($ch);
177
+ curl_close($ch);
178
+
179
+ } else {
180
+ $result = @file_get_contents( $url );
181
+ }
182
+
183
+ if ( $result ) {
184
+ // @todo set a transient with this data to reduce calls
185
+ wp_send_json_success( json_decode( $result ) );
186
+ } else {
187
+ wp_send_json_error(
188
+ array(
189
+ 'error' => 'apifailed',
190
+ 'msg' => __( 'The addons list could not be retrieved. Please <a href="">try again</a>. If the problem persists over time, please report it on the <a href="http://wordpress.org/support/plugin/restaurant-reservations" target="_blank">support forums</a>.', RTB_TEXTDOMAIN ),
191
+ )
192
+ );
193
+ }
194
+ }
195
+
196
+ }
197
+ } // endif;
includes/Settings.class.php CHANGED
@@ -206,7 +206,7 @@ Sorry, we could not accomodate your booking request. We\'re full or not open at
206
require_once( RTB_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php' );
207
$sap = sap_initialize_library(
208
$args = array(
209
- 'version' => '2.0.a.5',
210
'lib_url' => RTB_PLUGIN_URL . '/lib/simple-admin-pages/',
211
)
212
);
206
require_once( RTB_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php' );
207
$sap = sap_initialize_library(
208
$args = array(
209
+ 'version' => '2.0.a.7',
210
'lib_url' => RTB_PLUGIN_URL . '/lib/simple-admin-pages/',
211
)
212
);
includes/template-functions.php CHANGED
@@ -67,6 +67,72 @@ function rtb_print_booking_form() {
67
$booking_page = get_permalink( $booking_page );
68
}
69
70
ob_start();
71
72
?>
@@ -79,71 +145,30 @@ function rtb_print_booking_form() {
79
<?php else : ?>
80
<form method="POST" action="<?php echo esc_attr( $booking_page ); ?>">
81
<input type="hidden" name="action" value="booking_request">
82
- <fieldset class="reservation">
83
- <legend>
84
- <?php _e( 'Book a table', RTB_TEXTDOMAIN ); ?>
85
- </legend>
86
- <div class="date">
87
- <?php echo rtb_print_form_error( 'date' ); ?>
88
- <label for="rtb-date">
89
- <?php _e( 'Date', RTB_TEXTDOMAIN ); ?>
90
- </label>
91
- <input type="text" name="rtb-date" id="rtb-date" value="<?php echo empty( $request->request_date ) ? '' : esc_attr( $request->request_date ); ?>">
92
- </div>
93
- <div class="time">
94
- <?php echo rtb_print_form_error( 'time' ); ?>
95
- <label for="rtb-time">
96
- <?php _e( 'Time', RTB_TEXTDOMAIN ); ?>
97
- </label>
98
- <input type="text" name="rtb-time" id="rtb-time" value="<?php echo empty( $request->request_time ) ? '' : esc_attr( $request->request_time ); ?>">
99
- </div>
100
- <div class="party">
101
- <?php echo rtb_print_form_error( 'party' ); ?>
102
- <label for="rtb-party">
103
- <?php _e( 'Party', RTB_TEXTDOMAIN ); ?>
104
- </label>
105
- <input type="text" name="rtb-party" id="rtb-party" value="<?php echo empty( $request->party ) ? '' : esc_attr( $request->party ); ?>">
106
- </div>
107
- </fieldset>
108
- <fieldset class="contact">
109
<legend>
110
- <?php _e( 'Contact Details', RTB_TEXTDOMAIN ); ?>
111
</legend>
112
- <div class="name">
113
- <?php echo rtb_print_form_error( 'name' ); ?>
114
- <label for="rtb-name">
115
- <?php _e( 'Name', RTB_TEXTDOMAIN ); ?>
116
- </label>
117
- <input type="text" name="rtb-name" id="rtb-name" placeholder="Your name" value="<?php echo empty( $request->name ) ? '' : esc_attr( $request->name ); ?>">
118
- </div>
119
- <div class="email">
120
- <?php echo rtb_print_form_error( 'email' ); ?>
121
- <label for="rtb-email">
122
- <?php _e( 'Email', RTB_TEXTDOMAIN ); ?>
123
- </label>
124
- <input type="text" name="rtb-email" id="rtb-email" placeholder="your@email.com" value="<?php echo empty( $request->email ) ? '' : esc_attr( $request->email ); ?>">
125
- </div>
126
- <div class="phone">
127
- <?php echo rtb_print_form_error( 'phone' ); ?>
128
- <label for="rtb-phone">
129
- <?php _e( 'Phone', RTB_TEXTDOMAIN ); ?>
130
- </label>
131
- <input type="text" name="rtb-phone" id="rtb-phone" placeholder="Your phone number" value="<?php echo empty( $request->phone ) ? '' : esc_attr( $request->phone ); ?>">
132
- </div>
133
- <div class="add-message">
134
- <a href="#">
135
- <?php _e( 'Add a Message', RTB_TEXTDOMAIN ); ?>
136
- </a>
137
- </div>
138
- <div class="message">
139
- <?php echo rtb_print_form_error( 'message' ); ?>
140
- <label for="rtb-message">
141
- <?php _e( 'Message', RTB_TEXTDOMAIN ); ?>
142
- </label>
143
- <textarea name="rtb-message" id="rtb-message"><?php echo empty( $request->message ) ? '' : esc_attr( $request->message ); ?></textarea>
144
- </div>
145
</fieldset>
146
<button type="submit"><?php _e( 'Request Booking', RTB_TEXTDOMAIN ); ?></button>
147
</form>
148
<?php endif; ?>
149
</div>
@@ -265,6 +290,78 @@ function rtb_get_datepicker_rules() {
265
}
266
} // endif;
267
268
/**
269
* Print a form validation error
270
* @since 0.0.1
67
$booking_page = get_permalink( $booking_page );
68
}
69
70
+ // Define the form fields
71
+ //
72
+ // This array defines the field details and a callback function to
73
+ // render each field. To customize the form output, modify the
74
+ // callback functions to point to your custom function. Don't forget
75
+ // to output an error message in your custom callback function. You
76
+ // can use rtb_print_form_error( $slug ) to do this.
77
+ $fields = array(
78
+
79
+ // Reservation details fieldset
80
+ 'reservation' => array(
81
+ 'legend' => __( 'Book a table', RTB_TEXTDOMAIN ),
82
+ 'fields' => array(
83
+ 'date' => array(
84
+ 'title' => __( 'Date', RTB_TEXTDOMAIN ),
85
+ 'request_input' => empty( $request->request_date ) ? '' : $request->request_date,
86
+ 'callback' => 'rtb_print_form_text_field',
87
+ ),
88
+ 'time' => array(
89
+ 'title' => __( 'Time', RTB_TEXTDOMAIN ),
90
+ 'request_input' => empty( $request->request_time ) ? '' : $request->request_time,
91
+ 'callback' => 'rtb_print_form_text_field',
92
+ ),
93
+ 'party' => array(
94
+ 'title' => __( 'Party', RTB_TEXTDOMAIN ),
95
+ 'request_input' => empty( $request->party ) ? '' : $request->party,
96
+ 'callback' => 'rtb_print_form_text_field',
97
+ ),
98
+ ),
99
+ ),
100
+
101
+ // Contact details fieldset
102
+ 'contact' => array(
103
+ 'legend' => __( 'Contact Details', RTB_TEXTDOMAIN ),
104
+ 'fields' => array(
105
+ 'name' => array(
106
+ 'title' => __( 'Name', RTB_TEXTDOMAIN ),
107
+ 'request_input' => empty( $request->name ) ? '' : $request->name,
108
+ 'callback' => 'rtb_print_form_text_field',
109
+ ),
110
+ 'email' => array(
111
+ 'title' => __( 'Email', RTB_TEXTDOMAIN ),
112
+ 'request_input' => empty( $request->email ) ? '' : $request->email,
113
+ 'callback' => 'rtb_print_form_text_field',
114
+ ),
115
+ 'phone' => array(
116
+ 'title' => __( 'Phone', RTB_TEXTDOMAIN ),
117
+ 'request_input' => empty( $request->phone ) ? '' : $request->phone,
118
+ 'callback' => 'rtb_print_form_text_field',
119
+ ),
120
+ 'add-message' => array(
121
+ 'title' => __( 'Add a Message', RTB_TEXTDOMAIN ),
122
+ 'request_input' => '',
123
+ 'callback' => 'rtb_print_form_message_link',
124
+ ),
125
+ 'message' => array(
126
+ 'title' => __( 'Message', RTB_TEXTDOMAIN ),
127
+ 'request_input' => empty( $request->message ) ? '' : $request->message,
128
+ 'callback' => 'rtb_print_form_textarea_field',
129
+ ),
130
+ ),
131
+ ),
132
+ );
133
+
134
+ $fields = apply_filters( 'rtb_booking_form_fields', $fields, $request );
135
+
136
ob_start();
137
138
?>
145
<?php else : ?>
146
<form method="POST" action="<?php echo esc_attr( $booking_page ); ?>">
147
<input type="hidden" name="action" value="booking_request">
148
+
149
+ <?php do_action( 'rtb_booking_form_before_fields' ); ?>
150
+
151
+ <?php foreach( $fields as $fieldset => $contents ) : ?>
152
+ <fieldset class="<?php echo $fieldset; ?>">
153
+
154
+ <?php if ( !empty( $contents['legend'] ) ) : ?>
155
<legend>
156
+ <?php echo $contents['legend']; ?>
157
</legend>
158
+ <?php endif; ?>
159
+
160
+ <?php
161
+ foreach( $contents['fields'] as $slug => $field ) {
162
+ call_user_func( $field['callback'], $slug, $field['title'], $field['request_input'] );
163
+ }
164
+ ?>
165
</fieldset>
166
+ <?php endforeach; ?>
167
+
168
+ <?php do_action( 'rtb_booking_form_after_fields' ); ?>
169
+
170
<button type="submit"><?php _e( 'Request Booking', RTB_TEXTDOMAIN ); ?></button>
171
+
172
</form>
173
<?php endif; ?>
174
</div>
290
}
291
} // endif;
292
293
+ /**
294
+ * Print a text input form field
295
+ * @since 1.3
296
+ */
297
+ if ( !function_exists( 'rtb_print_form_text_field' ) ) {
298
+ function rtb_print_form_text_field( $slug, $title, $value ) {
299
+
300
+ $slug = esc_attr( $slug );
301
+ $value = esc_attr( $value );
302
+
303
+ ?>
304
+
305
+ <div class="<?php echo $slug; ?>">
306
+ <?php echo rtb_print_form_error( $slug ); ?>
307
+ <label for="rtb-<?php echo $slug; ?>">
308
+ <?php _e( $title, RTB_TEXTDOMAIN ); ?>
309
+ </label>
310
+ <input type="text" name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>" value="<?php echo $value; ?>">
311
+ </div>
312
+
313
+ <?php
314
+
315
+ }
316
+ } // endif;
317
+
318
+ /**
319
+ * Print a textarea form field
320
+ * @since 1.3
321
+ */
322
+ if ( !function_exists( 'rtb_print_form_textarea_field' ) ) {
323
+ function rtb_print_form_textarea_field( $slug, $title, $value ) {
324
+
325
+ $slug = esc_attr( $slug );
326
+
327
+ ?>
328
+
329
+ <div class="<?php echo $slug; ?>">
330
+ <?php echo rtb_print_form_error( $slug ); ?>
331
+ <label for="rtb-<?php echo $slug; ?>">
332
+ <?php _e( $title, RTB_TEXTDOMAIN ); ?>
333
+ </label>
334
+ <textarea name="rtb-<?php echo $slug; ?>" id="rtb-<?php echo $slug; ?>"><?php echo $value; ?></textarea>
335
+ </div>
336
+
337
+ <?php
338
+
339
+ }
340
+ } // endif;
341
+
342
+ /**
343
+ * Print the Add Message link to display the message field
344
+ * @since 1.3
345
+ */
346
+ if ( !function_exists( 'rtb_print_form_message_link' ) ) {
347
+ function rtb_print_form_message_link( $slug, $title, $value ) {
348
+
349
+ $slug = esc_attr( $slug );
350
+ $value = esc_attr( $value );
351
+
352
+ ?>
353
+
354
+ <div class="<?php echo $slug; ?>">
355
+ <a href="#">
356
+ <?php _e( $title, RTB_TEXTDOMAIN ); ?>
357
+ </a>
358
+ </div>
359
+
360
+ <?php
361
+
362
+ }
363
+ } // endif;
364
+
365
/**
366
* Print a form validation error
367
* @since 0.0.1
lib/simple-admin-pages/README.md CHANGED
@@ -38,7 +38,7 @@ Here's a simple example of how you can use this library to create an admin page.
38
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
39
$sap = sap_initialize_library(
40
array(
41
- 'version' => '2.0.a.5', // Version of the library
42
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
43
)
44
);
@@ -127,7 +127,7 @@ The lib_url is used to print stylesheets or scripts attached to the library.
127
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
128
$sap = sap_initialize_library(
129
$args = array(
130
- 'version' => '2.0.a.5', // Version of the library
131
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
132
)
133
);
38
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
39
$sap = sap_initialize_library(
40
array(
41
+ 'version' => '2.0.a.7', // Version of the library
42
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
43
)
44
);
127
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
128
$sap = sap_initialize_library(
129
$args = array(
130
+ 'version' => '2.0.a.7', // Version of the library
131
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
132
)
133
);
lib/simple-admin-pages/classes/AdminPage.Menu.class.php CHANGED
@@ -8,7 +8,7 @@
8
* @package Simple Admin Pages
9
*/
10
11
- class sapAdminPageMenu_2_0_a_5 extends sapAdminPage_2_0_a_5 {
12
13
public $setup_function = 'add_menu_page'; // WP function to register the page
14
8
* @package Simple Admin Pages
9
*/
10
11
+ class sapAdminPageMenu_2_0_a_7 extends sapAdminPage_2_0_a_7 {
12
13
public $setup_function = 'add_menu_page'; // WP function to register the page
14
lib/simple-admin-pages/classes/AdminPage.Submenu.class.php CHANGED
@@ -8,7 +8,7 @@
8
* @package Simple Admin Pages
9
*/
10
11
- class sapAdminPageSubmenu_2_0_a_5 extends sapAdminPage_2_0_a_5 {
12
13
public $setup_function = 'add_submenu_page'; // WP function to register the page
14
8
* @package Simple Admin Pages
9
*/
10
11
+ class sapAdminPageSubmenu_2_0_a_7 extends sapAdminPage_2_0_a_7 {
12
13
public $setup_function = 'add_submenu_page'; // WP function to register the page
14
lib/simple-admin-pages/classes/AdminPage.Themes.class.php CHANGED
@@ -8,7 +8,7 @@
8
* @package Simple Admin Pages
9
*/
10
11
- class sapAdminPageThemes_2_0_a_5 extends sapAdminPage_2_0_a_5 {
12
13
public $setup_function = 'add_theme_page'; // WP function to register the page
14
8
* @package Simple Admin Pages
9
*/
10
11
+ class sapAdminPageThemes_2_0_a_7 extends sapAdminPage_2_0_a_7 {
12
13
public $setup_function = 'add_theme_page'; // WP function to register the page
14
lib/simple-admin-pages/classes/AdminPage.class.php CHANGED
@@ -7,7 +7,7 @@
7
* @package Simple Admin Pages
8
*/
9
10
- class sapAdminPage_2_0_a_5 {
11
12
public $title;
13
public $menu_title;
7
* @package Simple Admin Pages
8
*/
9
10
+ class sapAdminPage_2_0_a_7 {
11
12
public $title;
13
public $menu_title;
lib/simple-admin-pages/classes/AdminPageSection.class.php CHANGED
@@ -7,7 +7,7 @@
7
* @package Simple Admin Pages
8
*/
9
10
- class sapAdminPageSection_2_0_a_5 {
11
12
// Page defaults
13
public $id; // unique id for this section
7
* @package Simple Admin Pages
8
*/
9
10
+ class sapAdminPageSection_2_0_a_7 {
11
12
// Page defaults
13
public $id; // unique id for this section
lib/simple-admin-pages/classes/AdminPageSetting.Address.class.php ADDED
@@ -0,0 +1,138 @@
1
+ <?php
2
+
3
+ /**
4
+ * Register, display and save a textarea field setting in the admin menu
5
+ *
6
+ * @since 2.0.a.5
7
+ * @package Simple Admin Pages
8
+ */
9
+
10
+ class sapAdminPageSettingAddress_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
11
+
12
+ /*
13
+ * Size of this textarea
14
+ *
15
+ * This is put directly into a css class [size]-text,
16
+ * and setting this to 'large' will link into WordPress's existing textarea
17
+ * style for full-width textareas.
18
+ */
19
+ public $size = 'small';
20
+
21
+ /**
22
+ * Scripts that must be loaded for this component
23
+ * @since 2.0.a.5
24
+ */
25
+ public $scripts = array(
26
+ 'sap-address' => array(
27
+ 'path' => 'js/address.js',
28
+ 'dependencies' => array( 'jquery' ),
29
+ 'version' => '2.0.a.5',
30
+ 'footer' => true,
31
+ ),
32
+ );
33
+
34
+ public $sanitize_callback = 'sanitize_text_field';
35
+
36
+ /**
37
+ * Escape the value to display it safely HTML textarea fields
38
+ * @since 2.0.a.5
39
+ */
40
+ public function esc_value( $val ) {
41
+
42
+ $escaped = array();
43
+ $escaped['text'] = empty( $val['text'] ) ? '' : esc_textarea( $val['text'] );
44
+ $escaped['lat'] = empty( $val['lat'] ) ? '' : esc_textarea( $val['lat'] );
45
+ $escaped['lon'] = empty( $val['lon'] ) ? '' : esc_textarea( $val['lon'] );
46
+
47
+ return $escaped;
48
+ }
49
+
50
+ /**
51
+ * Set the size of this textarea field
52
+ * @since 1.0
53
+ */
54
+ public function set_size( $size ) {
55
+ $this->size = esc_attr( $size );
56
+ }
57
+
58
+ /**
59
+ * Wrapper for the sanitization callback function.
60
+ *
61
+ * This just reduces code duplication for child classes that need a custom
62
+ * callback function.
63
+ * @since 2.0.a.5
64
+ */
65
+ public function sanitize_callback_wrapper( $value ) {
66
+
67
+ $sanitized = array();
68
+ $sanitized['text'] = empty( $value['text'] ) ? '' : wp_kses_post( $value['text'] );
69
+ $sanitized['lat'] = empty( $value['lat'] ) ? '' : sanitize_text_field( $value['lat'] );
70
+ $sanitized['lon'] = empty( $value['lon'] ) ? '' : sanitize_text_field( $value['lon'] );
71
+
72
+ return $sanitized;
73
+ }
74
+
75
+ /**
76
+ * Display this setting
77
+ * @since 2.0.a.5
78
+ */
79
+ public function display_setting() {
80
+
81
+ $strings = array(
82
+ 'sep-lat-lon' => _x( ', ', 'separates latitude and longitude', SAP_TEXTDOMAIN ),
83
+ 'no-setting' => __( 'No map coordinates set.', SAP_TEXTDOMAIN ),
84
+ 'retrieving' => __( 'Requesting new coordinates', SAP_TEXTDOMAIN ),
85
+ 'select' => __( 'Select a match below', SAP_TEXTDOMAIN ),
86
+ 'view' => __( 'View', SAP_TEXTDOMAIN ),
87
+ 'retrieve' => __( 'Retrieve map coordinates', SAP_TEXTDOMAIN ),
88
+ 'remove' => __( 'Remove map coordinates', SAP_TEXTDOMAIN ),
89
+ 'try_again' => __( 'Try again?', SAP_TEXTDOMAIN ),
90
+ 'result_error' => __( 'Error', SAP_TEXTDOMAIN ),
91
+ 'result_invalid' => __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', SAP_TEXTDOMAIN ),
92
+ 'result_denied' => __( 'Request denied.', SAP_TEXTDOMAIN ),
93
+ 'result_limit' => __( 'Request denied because you are over your request quota.', SAP_TEXTDOMAIN ),
94
+ 'result_empty' => __( 'Nothing was found at that address', SAP_TEXTDOMAIN ),
95
+ );
96
+
97
+ wp_localize_script(
98
+ 'sap-address',
99
+ 'sap_address',
100
+ array(
101
+ 'strings' => $strings,
102
+ )
103
+ );
104
+
105
+ $this->display_description();
106
+
107
+ ?>
108
+
109
+ <div class="sap-address" id="<?php echo $this->id; ?>">
110
+ <textarea name="<?php echo $this->get_input_name(); ?>[text]" id="<?php echo $this->get_input_name(); ?>" class="<?php echo $this->size; ?>-text"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?>><?php echo $this->value['text']; ?></textarea>
111
+ <p class="sap-map-coords-wrapper">
112
+ <span class="dashicons dashicons-location-alt"></span>
113
+ <span class="sap-map-coords">
114
+ <?php if ( empty( $this->value['lat'] ) || empty( $this->value['lon'] ) ) : ?>
115
+ <?php echo $strings['no-setting']; ?>
116
+ <?php else : ?>
117
+ <?php echo $this->value['lat'] . $strings['sep-lat-lon'] . $this->value['lon']; ?>
118
+ <a href="//maps.google.com/maps?q=<?php echo esc_attr( $this->value['lat'] ) . ',' . esc_attr( $this->value['lon'] ); ?>" class="sap-view-coords" target="_blank"><?php echo $strings['view']; ?></a>
119
+ <?php endif; ?>
120
+ </span>
121
+ </p>
122
+ <p class="sap-coords-action-wrapper">
123
+ <a href="#" class="sap-get-coords">
124
+ <?php echo $strings['retrieve']; ?>
125
+ </a>
126
+ <?php _ex( ' | ', 'separator between admin action links in address component', SAP_TEXTDOMAIN ); ?>
127
+ <a href="#" class="sap-remove-coords">
128
+ <?php echo $strings['remove']; ?>
129
+ </a>
130
+ </p>
131
+ <input type="hidden" class="lat" name="<?php echo $this->get_input_name(); ?>[lat]" value="<?php echo $this->value['lat']; ?>">
132
+ <input type="hidden" class="lon" name="<?php echo $this->get_input_name(); ?>[lon]" value="<?php echo $this->value['lon']; ?>">
133
+ </div>
134
+
135
+ <?php
136
+ }
137
+
138
+ }
lib/simple-admin-pages/classes/AdminPageSetting.Editor.class.php CHANGED
@@ -7,7 +7,7 @@
7
* @package Simple Admin Pages
8
*/
9
10
- class sapAdminPageSettingEditor_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
11
12
public $sanitize_callback = 'wp_kses_post';
13
7
* @package Simple Admin Pages
8
*/
9
10
+ class sapAdminPageSettingEditor_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
11
12
public $sanitize_callback = 'wp_kses_post';
13
lib/simple-admin-pages/classes/AdminPageSetting.HTML.class.php CHANGED
@@ -14,7 +14,7 @@
14
* @package Simple Admin Pages
15
*/
16
17
- class sapAdminPageSettingHTML_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
18
19
public $sanitize_callback = 'sanitize_text_field';
20
14
* @package Simple Admin Pages
15
*/
16
17
+ class sapAdminPageSettingHTML_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
18
19
public $sanitize_callback = 'sanitize_text_field';
20
lib/simple-admin-pages/classes/AdminPageSetting.OpeningHours.class.php CHANGED
@@ -25,7 +25,7 @@
25
* @package Simple Admin Pages
26
*/
27
28
- class sapAdminPageSettingOpeningHours_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
29
30
public $sanitize_callback = 'sanitize_text_field';
31
25
* @package Simple Admin Pages
26
*/
27
28
+ class sapAdminPageSettingOpeningHours_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
29
30
public $sanitize_callback = 'sanitize_text_field';
31
lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php CHANGED
@@ -10,7 +10,7 @@
10
* @package Simple Admin Pages
11
*/
12
13
- class sapAdminPageSettingScheduler_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
14
15
public $sanitize_callback = 'sanitize_text_field';
16
10
* @package Simple Admin Pages
11
*/
12
13
+ class sapAdminPageSettingScheduler_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
14
15
public $sanitize_callback = 'sanitize_text_field';
16
lib/simple-admin-pages/classes/AdminPageSetting.Select.class.php CHANGED
@@ -21,7 +21,7 @@
21
* @package Simple Admin Pages
22
*/
23
24
- class sapAdminPageSettingSelect_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
25
26
public $sanitize_callback = 'sanitize_text_field';
27
21
* @package Simple Admin Pages
22
*/
23
24
+ class sapAdminPageSettingSelect_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
25
26
public $sanitize_callback = 'sanitize_text_field';
27
lib/simple-admin-pages/classes/AdminPageSetting.SelectPost.class.php CHANGED
@@ -17,7 +17,7 @@
17
* @package Simple Admin Pages
18
*/
19
20
- class sapAdminPageSettingSelectPost_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
21
22
public $sanitize_callback = 'intval';
23
17
* @package Simple Admin Pages
18
*/
19
20
+ class sapAdminPageSettingSelectPost_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
21
22
public $sanitize_callback = 'intval';
23
lib/simple-admin-pages/classes/AdminPageSetting.SelectTaxonomy.class.php CHANGED
@@ -19,7 +19,7 @@
19
* @package Simple Admin Pages
20
*/
21
22
- class sapAdminPageSettingSelectTaxonomy_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
23
24
public $sanitize_callback = 'intval';
25
19
* @package Simple Admin Pages
20
*/
21
22
+ class sapAdminPageSettingSelectTaxonomy_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
23
24
public $sanitize_callback = 'intval';
25
lib/simple-admin-pages/classes/AdminPageSetting.Text.class.php CHANGED
@@ -7,7 +7,7 @@
7
* @package Simple Admin Pages
8
*/
9
10
- class sapAdminPageSettingText_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
11
12
public $sanitize_callback = 'sanitize_text_field';
13
7
* @package Simple Admin Pages
8
*/
9
10
+ class sapAdminPageSettingText_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
11
12
public $sanitize_callback = 'sanitize_text_field';
13
lib/simple-admin-pages/classes/AdminPageSetting.Textarea.class.php CHANGED
@@ -9,7 +9,7 @@
9
* @todo textareas should have an option to swap new lines for <br>s
10
*/
11
12
- class sapAdminPageSettingTextarea_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
13
14
/*
15
* Size of this textarea
9
* @todo textareas should have an option to swap new lines for <br>s
10
*/
11
12
+ class sapAdminPageSettingTextarea_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
13
14
/*
15
* Size of this textarea
lib/simple-admin-pages/classes/AdminPageSetting.Toggle.class.php CHANGED
@@ -17,7 +17,7 @@
17
* @package Simple Admin Pages
18
*/
19
20
- class sapAdminPageSettingToggle_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
21
22
public $sanitize_callback = 'sanitize_text_field';
23
17
* @package Simple Admin Pages
18
*/
19
20
+ class sapAdminPageSettingToggle_2_0_a_7 extends sapAdminPageSetting_2_0_a_7 {
21
22
public $sanitize_callback = 'sanitize_text_field';
23
lib/simple-admin-pages/classes/AdminPageSetting.class.php CHANGED
@@ -15,7 +15,7 @@
15
* @package Simple Admin Pages
16
*/
17
18
- abstract class sapAdminPageSetting_2_0_a_5 {
19
20
// Page defaults
21
public $id; // used in form fields and database to track and store setting
15
* @package Simple Admin Pages
16
*/
17
18
+ abstract class sapAdminPageSetting_2_0_a_7 {
19
20
// Page defaults
21
public $id; // used in form fields and database to track and store setting
lib/simple-admin-pages/classes/Library.class.php CHANGED
@@ -1,5 +1,5 @@
1
<?php
2
- if ( !class_exists( 'sapLibrary_2_0_a_5' ) ) {
3
/**
4
* This library class loads and provides access to the correct version of the
5
* Simple Admin Pages library.
@@ -7,10 +7,10 @@ if ( !class_exists( 'sapLibrary_2_0_a_5' ) ) {
7
* @since 1.0
8
* @package Simple Admin Pages
9
*/
10
- class sapLibrary_2_0_a_5 {
11
12
// Version of the library
13
- private $version = '2.0.a.5';
14
15
// A full URL to the library which is used to correctly link scripts and
16
// stylesheets.
@@ -161,6 +161,10 @@ class sapLibrary_2_0_a_5 {
161
require_once('AdminPageSetting.OpeningHours.class.php');
162
return $this->get_versioned_classname( 'sapAdminPageSettingOpeningHours' );
163
164
default :
165
166
// Exit early if a custom type is declared without providing the
@@ -176,6 +180,11 @@ class sapLibrary_2_0_a_5 {
176
require_once( $type['filename'] );
177
} elseif ( isset( $this->lib_extension_path ) && file_exists( $this->lib_extension_path . $type['filename'] ) ) {
178
require_once( $this->lib_extension_path . '/' . $type['filename'] );
179
} else {
180
return false;
181
}
@@ -260,7 +269,7 @@ class sapLibrary_2_0_a_5 {
260
}
261
262
$class = $this->get_setting_classname( $type );
263
- if ( ( $class && class_exists( $class ) ) && is_subclass_of( $class, $this->get_versioned_classname( 'sapAdminPageSetting' ) ) ) {
264
$this->pages[ $page ]->sections[ $section ]->add_setting( new $class( $args ) );
265
}
266
@@ -370,26 +379,29 @@ class sapLibrary_2_0_a_5 {
370
/**
371
* Enqueue the stylesheets and scripts
372
* @since 1.0
373
- * @todo complex settings should enqueue their assets only when loaded
374
*/
375
public function enqueue_scripts() {
376
377
- // Enqueue assets for specific settings
378
- foreach ( $this->pages as $page ) {
379
- foreach ( $page->sections as $section ) {
380
- foreach ( $section->settings as $setting ) {
381
- foreach( $setting->scripts as $handle => $script ) {
382
- wp_enqueue_script( $handle, $this->lib_url . $script['path'], $script['dependencies'], $script['version'], $script['footer'] );
383
- }
384
- foreach( $setting->styles as $handle => $style ) {
385
- wp_enqueue_style( $handle . '-' . $this->version, $this->lib_url . $style['path'], $style['dependencies'], $style['version'], $style['media'] );
386
}
387
}
388
}
389
}
390
-
391
- // Default styles and scripts
392
- wp_enqueue_style( 'sap-admin-style-' . $this->version, $this->lib_url . 'css/admin.css' );
393
}
394
395
/**
1
<?php
2
+ if ( !class_exists( 'sapLibrary_2_0_a_7' ) ) {
3
/**
4
* This library class loads and provides access to the correct version of the
5
* Simple Admin Pages library.
7
* @since 1.0
8
* @package Simple Admin Pages
9
*/
10
+ class sapLibrary_2_0_a_7 {
11
12
// Version of the library
13
+ private $version = '2.0.a.7';
14
15
// A full URL to the library which is used to correctly link scripts and
16
// stylesheets.
161
require_once('AdminPageSetting.OpeningHours.class.php');
162
return $this->get_versioned_classname( 'sapAdminPageSettingOpeningHours' );
163
164
+ case 'address' :
165
+ require_once('AdminPageSetting.Address.class.php');
166
+ return $this->get_versioned_classname( 'sapAdminPageSettingAddress' );
167
+
168
default :
169
170
// Exit early if a custom type is declared without providing the
180
require_once( $type['filename'] );
181
} elseif ( isset( $this->lib_extension_path ) && file_exists( $this->lib_extension_path . $type['filename'] ) ) {
182
require_once( $this->lib_extension_path . '/' . $type['filename'] );
183
+ if ( !class_exists( $type['class'] ) ) {
184
+ return false;
185
+ } else {
186
+ return $type['class'];
187
+ }
188
} else {
189
return false;
190
}
269
}
270
271
$class = $this->get_setting_classname( $type );
272
+ if ( $class && class_exists( $class ) ) {
273
$this->pages[ $page ]->sections[ $section ]->add_setting( new $class( $args ) );
274
}
275
379
/**
380
* Enqueue the stylesheets and scripts
381
* @since 1.0
382
*/
383
public function enqueue_scripts() {
384
+
385
+ $screen = get_current_screen();
386
387
+ foreach ( $this->pages as $page_id => $page ) {
388
+
389
+ // Only enqueue assets for the current page
390
+ if ( strpos( $screen->base, $page_id ) !== false ) {
391
+ wp_enqueue_style( 'sap-admin-style-' . $this->version, $this->lib_url . 'css/admin.css' );
392
+
393
+ foreach ( $page->sections as $section ) {
394
+ foreach ( $section->settings as $setting ) {
395
+ foreach( $setting->scripts as $handle => $script ) {
396
+ wp_enqueue_script( $handle, $this->lib_url . $script['path'], $script['dependencies'], $script['version'], $script['footer'] );
397
+ }
398
+ foreach( $setting->styles as $handle => $style ) {
399
+ wp_enqueue_style( $handle, $this->lib_url . $style['path'], $style['dependencies'], $style['version'], $style['media'] );
400
+ }
401
}
402
}
403
}
404
}
405
}
406
407
/**
lib/simple-admin-pages/js/address.js ADDED
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Javascript functions for Address component
3
+ *
4
+ * @package Simple Admin Pages
5
+ */
6
+
7
+ jQuery(document).ready(function ($) {
8
+
9
+ /**
10
+ * Set coordinate that have been received
11
+ */
12
+ function sap_address_set_coords( control, lat, lon ) {
13
+ control.find( '.sap-coords-result' ).remove();
14
+ control.find( 'input.lat' ).val( lat );
15
+ control.find( 'input.lon' ).val( lon );
16
+
17
+ if ( lat == '' && lon == '' ) {
18
+ control.find( '.sap-map-coords' ).text( lat + sap_address.strings['no-setting'] + lon ).attr( 'style', '' );
19
+ } else {
20
+ control.find( '.sap-map-coords' ).text( lat + sap_address.strings['sep-lat-lon'] + lon ).attr( 'style', '' );
21
+ }
22
+
23
+ var url = '//maps.google.com/maps?q=' + lat + ',' + lon;
24
+ if ( control.find( '.sap-view-coords' ).length ) {
25
+ control.find( '.sap-view-coords' ).attr( 'href', url );
26
+ } else {
27
+ control.find( '.sap-map-coords-wrapper' ).append( '<a class="sap-view-coords" href="' + url + '" target="_blank">' + sap_address.strings.view + '</a>' );
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Retrieve coordinates
33
+ */
34
+ $('.sap-get-coords').click( function() {
35
+ var control = $(this).parent().parent();
36
+ var address = control.find( 'textarea' ).val();
37
+
38
+ // Reset messages
39
+ control.find( '.sap-coords-result' ).remove();
40
+ control.find( '.error' ).remove();
41
+ control.find( '.sap-view-coords' ).remove();
42
+ control.find( '.sap-map-coords' ).text( sap_address.strings.retrieving ).attr( 'style', 'opacity: 0.3' );
43
+
44
+ // Call Google Maps geocoding API
45
+ // See: https://developers.google.com/maps/documentation/geocoding/
46
+ var req = $.get(
47
+ '//maps.googleapis.com/maps/api/geocode/json',
48
+ { sensor: false, address: address },
49
+ function( data ) {
50
+
51
+ if ( data.status == 'OK' ) {
52
+ if ( data.results.length == 1 ) {
53
+ sap_address_set_coords( control, data.results[0].geometry.location.lat, data.results[0].geometry.location.lng );
54
+
55
+ } else {
56
+ for ( var key in data.results ) {
57
+ control.append( '<p class="sap-coords-result">' + data.results[key].formatted_address + ' <span class="dashicons dashicons-arrow-right"></span> <a href="#" data-lat="' + data.results[key].geometry.location.lat + '" data-lon="' + data.results[key].geometry.location.lng + '">Set</a></p>' );
58
+ }
59
+ control.find( '.sap-map-coords' ).text( sap_address.strings.select ).attr( 'style', '' );
60
+
61
+ control.find( '.sap-coords-result a' ).click( function() {
62
+ sap_address_set_coords( control, $(this).data( 'lat' ), $(this).data( 'lon' ) );
63
+ });
64
+
65
+ }
66
+
67
+ } else {
68
+ sap_address_set_coords( control, control.find( 'input.lat' ).val(), control.find( 'input.lon' ).val() );
69
+
70
+ if ( data.status == 'UNKNOWN_ERROR' ) {
71
+ control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_error + '</div>' );
72
+ } else if ( data.status == 'INVALID_REQUEST' ) {
73
+ control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_invalid + '</div>' );
74
+ } else if ( data.status == 'INVALID_REQUEST' ) {
75
+ control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_error + '</div>' );
76
+ } else if ( data.status == 'REQUEST_DENIED' ) {
77
+ control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_denied + '</div>' );
78
+ } else if ( data.status == 'OVER_QUERY_LIMIT' ) {
79
+ control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_limit + '</div>' );
80
+ } else if ( data.status == 'ZERO_RESULTS' ) {
81
+ control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_empty + '</div>' );
82
+ }
83
+ }
84
+ }
85
+ )
86
+ });
87
+
88
+ /**
89
+ * Remove coordinates from settings
90
+ */
91
+ $('.sap-remove-coords').click( function() {
92
+ var control = $(this).parent().parent();
93
+ sap_address_set_coords( control, '', '' );
94
+ });
95
+
96
+ });
lib/simple-admin-pages/js/scheduler.js CHANGED
@@ -284,6 +284,54 @@ jQuery(document).ready(function ($) {
284
}
285
}
286
287
/**
288
* Register click events on load
289
*/
@@ -295,12 +343,12 @@ jQuery(document).ready(function ($) {
295
if ( typeof sap_scheduler.settings != 'undefined' ) {
296
for ( var key in sap_scheduler.settings ) {
297
var obj = sap_scheduler.settings[key];
298
- $( '#' + key + ' .sap-scheduler-date-input input' ).pickadate({
299
- format: obj.date_format,
300
- });
301
- $( '#' + key + ' .sap-scheduler-time-input input' ).pickatime({
302
- interval: obj.time_interval,
303
- format: obj.time_format,
304
});
305
}
306
}
@@ -313,13 +361,8 @@ jQuery(document).ready(function ($) {
313
var scheduler_id = scheduler.attr( 'id' );
314
var scheduler_settings = sap_scheduler.settings[ scheduler_id ];
315
scheduler.append( scheduler_settings.template.replace( /\[0\]/g, '[' + scheduler.children( '.sap-scheduler-rule' ).length + ']' ) );
316
- scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-date-input input' ).pickadate({
317
- format: scheduler_settings.date_format,
318
- });
319
- scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-time-input input' ).pickatime({
320
- interval: scheduler_settings.time_interval,
321
- format: scheduler_settings.time_format,
322
- });
323
sap_scheduler_register_events();
324
325
return false;
284
}
285
}
286
287
+ /**
288
+ * Register a new datepicker on an element
289
+ */
290
+ function sap_scheduler_register_datepicker( el ) {
291
+
292
+ el.pickadate({
293
+ format: obj.date_format,
294
+ formatSubmit: 'yyyy/mm/dd',
295
+ hiddenName: true,
296
+
297
+ // Select the value when loaded if a value has been set
298
+ onStart: function() {
299
+ if ( this.get() !== '' ) {
300
+ var date = new Date( this.get() );
301
+ if ( Object.prototype.toString.call( date ) === "[object Date]" ) {
302
+ this.set( 'select', date );
303
+ }
304
+ }
305
+ }
306
+ });
307
+ }
308
+
309
+ /**
310
+ * Register a new timepicker on an element
311
+ */
312
+ function sap_scheduler_register_timepicker( el ) {
313
+
314
+ el.pickatime({
315
+ interval: obj.time_interval,
316
+ format: obj.time_format,
317
+ formatSubmit: 'h:i A',
318
+ hiddenName: true,
319
+
320
+ // Select the value when loaded if a value has been set
321
+ onStart: function() {
322
+ if ( this.get() !== '' ) {
323
+ var today = new Date();
324
+ var today_date = today.getFullYear() + '/' + ( today.getMonth() + 1 ) + '/' + today.getDate();
325
+ var time = new Date( today_date + ' ' + this.get() );
326
+ if ( Object.prototype.toString.call( time ) === "[object Date]" ) {
327
+ this.set( 'select', time );
328
+ }
329
+ }
330
+ }
331
+ });
332
+ }
333
+
334
+
335
/**
336
* Register click events on load
337
*/
343
if ( typeof sap_scheduler.settings != 'undefined' ) {
344
for ( var key in sap_scheduler.settings ) {
345
var obj = sap_scheduler.settings[key];
346
+ sap_scheduler_register_datepicker( $( '#' + key + ' .sap-scheduler-date-input input[type="text"]' ) );
347
+ sap_scheduler_register_timepicker( $( '#' + key + ' .sap-scheduler-time-input input[type="text"]' ) );
348
+
349
+ $( '#' + key + ' .sap-scheduler-rule' ).each( function() {
350
+ sap_scheduler_set_date_phrase( $(this), $( '#' + key ).attr( 'id' ) );
351
+ sap_scheduler_set_time_phrase( $(this), $( '#' + key ).attr( 'id' ) );
352
});
353
}
354
}
361
var scheduler_id = scheduler.attr( 'id' );
362
var scheduler_settings = sap_scheduler.settings[ scheduler_id ];
363
scheduler.append( scheduler_settings.template.replace( /\[0\]/g, '[' + scheduler.children( '.sap-scheduler-rule' ).length + ']' ) );
364
+ sap_scheduler_register_datepicker( scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-date-input input[type="text"]' ) );
365
+ sap_scheduler_register_timepicker( scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-time-input input[type="text"]' ) );
366
sap_scheduler_register_events();
367
368
return false;
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: NateWr
3
Author URI: https://github.com/NateWr
4
Plugin URL: http://themeofthecrop.com
5
Requires at Least: 3.8
6
- Tested Up To: 3.9.1
7
Tags: restaurant, reservations, bookings, table bookings, restaurant reservation, table reservation
8
- Stable tag: 1.2.1
9
License: GPLv2 or later
10
Donate link: http://themeofthecrop.com
11
@@ -31,8 +31,8 @@ This plugin is part of a group of plugins for restaurants. Check out the [Food a
31
32
There is a short guide to using the plugin in the /docs/ folder. It can be accessed by following the Help link listed under the plugin on the Plugins page in your WordPress admin area. Not sure where that is? One of the [screenshots](http://wordpress.org/plugins/restaurant-reservations/screenshots/) for this plugin will show you where to find it.
33
34
- = MailChimp addon beta =
35
- A commercial addon for this plugin is in development that will allow you to subscribe new reservations to your MailChimp mailing list. The plugin is currently in a short beta period before release. I'm offering a free license to anyone who participates. [Learn more](http://themeofthecrop.com/2014/08/18/mailchimp-restaurant-reservations-ready-beta/).
36
37
= Developers =
38
@@ -59,6 +59,13 @@ This plugin is packed with hooks so you can extend it, customize it and rebrand
59
60
== Changelog ==
61
62
= 1.2.1 (2014-08-01) =
63
* Fix: bulk actions below the bookings table don't work
64
* Fix: PHP Notice generated during validation
@@ -102,6 +109,9 @@ This plugin is packed with hooks so you can extend it, customize it and rebrand
102
103
== Upgrade Notice ==
104
105
= 1.2.1 =
106
This is a minor maintenance update which fixes a couple of small bugs.
107
3
Author URI: https://github.com/NateWr
4
Plugin URL: http://themeofthecrop.com
5
Requires at Least: 3.8
6
+ Tested Up To: 4.0
7
Tags: restaurant, reservations, bookings, table bookings, restaurant reservation, table reservation
8
+ Stable tag: 1.2.2
9
License: GPLv2 or later
10
Donate link: http://themeofthecrop.com
11
31
32
There is a short guide to using the plugin in the /docs/ folder. It can be accessed by following the Help link listed under the plugin on the Plugins page in your WordPress admin area. Not sure where that is? One of the [screenshots](http://wordpress.org/plugins/restaurant-reservations/screenshots/) for this plugin will show you where to find it.
33
34
+ = Addons =
35
+ [MailChimp for Restaurant Reservations](http://themeofthecrop.com/2014/08/18/mailchimp-restaurant-reservations-ready-beta/?utm_source=Plugin&utm_medium=Plugin%20Description&utm_campaign=Restaurant%20Reservations) - Subscribe emails from new restaurant reservations to your MailChimp mailing list.
36
37
= Developers =
38
59
60
== Changelog ==
61
62
+ = 1.2.2 (2014-08-24) =
63
+ * Fix: custom date formats can break date validation for new bookings
64
+ * Add new booking form generation hooks for easier customization
65
+ * Add support for upcoming MailChimp addon
66
+ * Add new addons page
67
+ * Update Simple Admin Pages library to v2.0.a.7
68
+
69
= 1.2.1 (2014-08-01) =
70
* Fix: bulk actions below the bookings table don't work
71
* Fix: PHP Notice generated during validation
109
110
== Upgrade Notice ==
111
112
+ = 1.2.2 =
113
+ This update adds support for a new MailChimp addon that will be released soon. An addons page is now available under the Bookings menu. A bug in which custom date/time formats could cause validation errors has been fixed. New hooks are now in place so that it's easier to customize the form output.
114
+
115
= 1.2.1 =
116
This is a minor maintenance update which fixes a couple of small bugs.
117
restaurant-reservations.php CHANGED
@@ -3,7 +3,7 @@
3
* Plugin Name: Restaurant Reservations
4
* Plugin URI: http://themeofthecrop.com
5
* Description: Accept restaurant reservations and bookings online.
6
- * Version: 1.2.1
7
* Author: Theme of the Crop
8
* Author URI: http://themeofthecrop.com
9
* License: GNU General Public License v2.0 or later
@@ -92,6 +92,15 @@ class rtbInit {
92
// Add links to plugin listing
93
add_filter('plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2);
94
95
}
96
97
/**
@@ -221,7 +230,7 @@ class rtbInit {
221
public function enqueue_admin_assets() {
222
223
$screen = get_current_screen();
224
- if ( $screen->base == 'toplevel_page_rtb-bookings' || $screen->base == 'bookings_page_rtb-settings' ) {
225
wp_enqueue_style( 'rtb-admin', RTB_PLUGIN_URL . '/assets/css/admin.css' );
226
wp_enqueue_script( 'rtb-admin', RTB_PLUGIN_URL . '/assets/js/admin.js', array( 'jquery' ), '', true );
227
}
@@ -286,4 +295,4 @@ class rtbInit {
286
}
287
} // endif;
288
289
- $rtb_controller = new rtbInit();
3
* Plugin Name: Restaurant Reservations
4
* Plugin URI: http://themeofthecrop.com
5
* Description: Accept restaurant reservations and bookings online.
6
+ * Version: 1.2.2
7
* Author: Theme of the Crop
8
* Author URI: http://themeofthecrop.com
9
* License: GNU General Public License v2.0 or later
92
// Add links to plugin listing
93
add_filter('plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2);
94
95
+ // Add the addons page
96
+ require_once( RTB_PLUGIN_DIR . '/includes/Addons.class.php' );
97
+ new rtbAddons(
98
+ array(
99
+ 'api_url' => 'http://api.themeofthecrop.com/addons/',
100
+ 'plugin' => basename( plugin_dir_path( __FILE__ ) ),
101
+ )
102
+ );
103
+
104
}
105
106
/**
230
public function enqueue_admin_assets() {
231
232
$screen = get_current_screen();
233
+ if ( $screen->base == 'toplevel_page_rtb-bookings' || $screen->base == 'bookings_page_rtb-settings' || $screen->base == 'bookings_page_rtb-addons' ) {
234
wp_enqueue_style( 'rtb-admin', RTB_PLUGIN_URL . '/assets/css/admin.css' );
235
wp_enqueue_script( 'rtb-admin', RTB_PLUGIN_URL . '/assets/js/admin.js', array( 'jquery' ), '', true );
236
}
295
}
296
} // endif;
297
298
+ $rtb_controller = new rtbInit();