Version Description
Download this release
Release Info
Developer | Ladela |
Plugin | WordPress Online Booking and Scheduling Plugin – Bookly |
Version | 18.5 |
Comparing to | |
See all releases |
Code changes from version 18.4 to 18.5
- backend/components/dialogs/queue/resources/js/queue-dialog.js +7 -3
- backend/components/dialogs/service/edit/resources/js/service-edit-dialog.js +7 -2
- backend/components/tiny_mce/resources/js/bookly-form-settings.js +14 -14
- backend/modules/appointments/resources/js/appointments.js +3 -2
- backend/modules/appointments/templates/index.php +1 -1
- backend/modules/calendar/Page.php +1 -1
- backend/modules/calendar/resources/js/calendar.js +6 -2
- backend/modules/customers/resources/js/customers.js +2 -2
- backend/modules/customers/templates/index.php +1 -1
- backend/modules/payments/resources/js/payments.js +1 -1
- backend/modules/payments/templates/index.php +1 -1
- backend/modules/services/resources/js/services-list.js +4 -3
- backend/modules/staff/resources/js/staff-list.js +1 -1
- frontend/components/booking/InfoText.php +4 -4
- lib/CartItem.php +13 -13
- lib/Updater.php +6 -6
- lib/entities/Service.php +19 -5
- main.php +1 -1
- readme.txt +2 -2
backend/components/dialogs/queue/resources/js/queue-dialog.js
CHANGED
@@ -6,14 +6,18 @@ jQuery(function ($) {
|
|
6 |
$template = $('#bookly-notification-template')
|
7 |
;
|
8 |
|
|
|
|
|
|
|
|
|
9 |
$queue.html('');
|
10 |
queue.forEach(function (notification, index) {
|
11 |
$queue.append(
|
12 |
$template.clone().show().html()
|
13 |
.replace(/{{icon}}/g, notification.gateway == 'sms' ? 'fas fa-sms' : 'far fa-envelope')
|
14 |
-
.replace(/{{recipient}}/g, notification.data.name)
|
15 |
-
.replace(/{{address}}/g, notification.address)
|
16 |
-
.replace(/{{description}}/g, notification.name)
|
17 |
.replace(/{{index}}/g, index)
|
18 |
);
|
19 |
});
|
6 |
$template = $('#bookly-notification-template')
|
7 |
;
|
8 |
|
9 |
+
function encodeHTML(s) {
|
10 |
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
11 |
+
}
|
12 |
+
|
13 |
$queue.html('');
|
14 |
queue.forEach(function (notification, index) {
|
15 |
$queue.append(
|
16 |
$template.clone().show().html()
|
17 |
.replace(/{{icon}}/g, notification.gateway == 'sms' ? 'fas fa-sms' : 'far fa-envelope')
|
18 |
+
.replace(/{{recipient}}/g, encodeHTML(notification.data.name))
|
19 |
+
.replace(/{{address}}/g, encodeHTML(notification.address))
|
20 |
+
.replace(/{{description}}/g, encodeHTML(notification.name))
|
21 |
.replace(/{{index}}/g, index)
|
22 |
);
|
23 |
});
|
backend/components/dialogs/service/edit/resources/js/service-edit-dialog.js
CHANGED
@@ -27,7 +27,8 @@ jQuery(function ($) {
|
|
27 |
}
|
28 |
});
|
29 |
$servicesList.on('click', '[data-action="edit"]', function () {
|
30 |
-
let
|
|
|
31 |
$containers.html('');
|
32 |
$serviceTabs.hide();
|
33 |
$serviceLoading.show();
|
@@ -76,7 +77,7 @@ jQuery(function ($) {
|
|
76 |
// Providers preference.
|
77 |
$.each(response.data.staff, function (index, category) {
|
78 |
$.each(category.items, function (index, staff) {
|
79 |
-
staff_data[staff.id] = staff.full_name;
|
80 |
});
|
81 |
});
|
82 |
$staffPreference.on('change', function () {
|
@@ -223,6 +224,10 @@ jQuery(function ($) {
|
|
223 |
/**
|
224 |
* Local functions
|
225 |
*/
|
|
|
|
|
|
|
|
|
226 |
function initColorPicker($jquery_collection) {
|
227 |
$jquery_collection.each(function () {
|
228 |
$(this).data('last-color', $(this).val());
|
27 |
}
|
28 |
});
|
29 |
$servicesList.on('click', '[data-action="edit"]', function () {
|
30 |
+
let $tr = $(this).closest('tr'),
|
31 |
+
data = $servicesList.DataTable().row($tr.hasClass('child') ? $tr.prev() : $tr).data();
|
32 |
$containers.html('');
|
33 |
$serviceTabs.hide();
|
34 |
$serviceLoading.show();
|
77 |
// Providers preference.
|
78 |
$.each(response.data.staff, function (index, category) {
|
79 |
$.each(category.items, function (index, staff) {
|
80 |
+
staff_data[staff.id] = encodeHTML(staff.full_name);
|
81 |
});
|
82 |
});
|
83 |
$staffPreference.on('change', function () {
|
224 |
/**
|
225 |
* Local functions
|
226 |
*/
|
227 |
+
function encodeHTML(s) {
|
228 |
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
229 |
+
}
|
230 |
+
|
231 |
function initColorPicker($jquery_collection) {
|
232 |
$jquery_collection.each(function () {
|
233 |
$(this).data('last-color', $(this).val());
|
backend/components/tiny_mce/resources/js/bookly-form-settings.js
CHANGED
@@ -64,7 +64,7 @@ jQuery(function ($) {
|
|
64 |
}
|
65 |
|
66 |
function setSelects(location_id, category_id, service_id, staff_id) {
|
67 |
-
var _location_id = (BooklyFormShortCodeL10n.locationCustom && location_id) ? location_id : 0
|
68 |
var _staff = {}, _services = {}, _categories = {}, _nop = {}, _max_capacity = null, _min_capacity = null;
|
69 |
$.each(BooklyFormShortCodeL10n.staff, function (id, staff_member) {
|
70 |
if (!location_id || BooklyFormShortCodeL10n.locations[location_id].staff.hasOwnProperty(id)) {
|
@@ -145,9 +145,9 @@ jQuery(function ($) {
|
|
145 |
// Location select change
|
146 |
$select_location.on('change', function () {
|
147 |
var location_id = this.value,
|
148 |
-
category_id = $select_category.val(),
|
149 |
-
service_id
|
150 |
-
staff_id
|
151 |
;
|
152 |
|
153 |
// Validate selected values.
|
@@ -190,10 +190,10 @@ jQuery(function ($) {
|
|
190 |
|
191 |
// Category select change
|
192 |
$select_category.on('change', function () {
|
193 |
-
var location_id = $select_location.val(),
|
194 |
category_id = this.value,
|
195 |
-
service_id
|
196 |
-
staff_id
|
197 |
;
|
198 |
|
199 |
// Validate selected values.
|
@@ -221,10 +221,10 @@ jQuery(function ($) {
|
|
221 |
|
222 |
// Service select change
|
223 |
$select_service.on('change', function () {
|
224 |
-
var location_id = $select_location.val(),
|
225 |
category_id = '',
|
226 |
-
service_id
|
227 |
-
staff_id
|
228 |
;
|
229 |
|
230 |
// Validate selected values.
|
@@ -294,10 +294,10 @@ jQuery(function ($) {
|
|
294 |
|
295 |
// Staff select change
|
296 |
$select_employee.on('change', function () {
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
;
|
302 |
|
303 |
setSelects(location_id, category_id, service_id, staff_id);
|
64 |
}
|
65 |
|
66 |
function setSelects(location_id, category_id, service_id, staff_id) {
|
67 |
+
var _location_id = (BooklyFormShortCodeL10n.locationCustom == '1' && location_id) ? location_id : 0;
|
68 |
var _staff = {}, _services = {}, _categories = {}, _nop = {}, _max_capacity = null, _min_capacity = null;
|
69 |
$.each(BooklyFormShortCodeL10n.staff, function (id, staff_member) {
|
70 |
if (!location_id || BooklyFormShortCodeL10n.locations[location_id].staff.hasOwnProperty(id)) {
|
145 |
// Location select change
|
146 |
$select_location.on('change', function () {
|
147 |
var location_id = this.value,
|
148 |
+
category_id = $select_category.val()||'',
|
149 |
+
service_id = $select_service.val()||'',
|
150 |
+
staff_id = $select_employee.val()||''
|
151 |
;
|
152 |
|
153 |
// Validate selected values.
|
190 |
|
191 |
// Category select change
|
192 |
$select_category.on('change', function () {
|
193 |
+
var location_id = $select_location.val()||'',
|
194 |
category_id = this.value,
|
195 |
+
service_id = $select_service.val()||'',
|
196 |
+
staff_id = $select_employee.val()||''
|
197 |
;
|
198 |
|
199 |
// Validate selected values.
|
221 |
|
222 |
// Service select change
|
223 |
$select_service.on('change', function () {
|
224 |
+
var location_id = $select_location.val()||'',
|
225 |
category_id = '',
|
226 |
+
service_id = this.value,
|
227 |
+
staff_id = $select_employee.val()||''
|
228 |
;
|
229 |
|
230 |
// Validate selected values.
|
294 |
|
295 |
// Staff select change
|
296 |
$select_employee.on('change', function () {
|
297 |
+
var location_id = $select_location.val()||'',
|
298 |
+
category_id = $select_category.val()||'',
|
299 |
+
service_id = $select_service.val()||'',
|
300 |
+
staff_id = this.value
|
301 |
;
|
302 |
|
303 |
setSelects(location_id, category_id, service_id, staff_id);
|
backend/modules/appointments/resources/js/appointments.js
CHANGED
@@ -115,7 +115,7 @@ jQuery(function($) {
|
|
115 |
columns.push({data: 'customer.email', render: $.fn.dataTable.render.text()});
|
116 |
break;
|
117 |
case 'staff_name':
|
118 |
-
columns.push({data: 'staff.name'});
|
119 |
break;
|
120 |
case 'service_title':
|
121 |
columns.push({
|
@@ -174,6 +174,7 @@ jQuery(function($) {
|
|
174 |
break;
|
175 |
case 'number_of_persons':
|
176 |
case 'locations':
|
|
|
177 |
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
178 |
break;
|
179 |
case 'online_meeting':
|
@@ -197,7 +198,7 @@ jQuery(function($) {
|
|
197 |
orderable: false
|
198 |
});
|
199 |
} else {
|
200 |
-
columns.push({data: column});
|
201 |
}
|
202 |
break;
|
203 |
}
|
115 |
columns.push({data: 'customer.email', render: $.fn.dataTable.render.text()});
|
116 |
break;
|
117 |
case 'staff_name':
|
118 |
+
columns.push({data: 'staff.name', render: $.fn.dataTable.render.text()});
|
119 |
break;
|
120 |
case 'service_title':
|
121 |
columns.push({
|
174 |
break;
|
175 |
case 'number_of_persons':
|
176 |
case 'locations':
|
177 |
+
case 'notes':
|
178 |
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
179 |
break;
|
180 |
case 'online_meeting':
|
198 |
orderable: false
|
199 |
});
|
200 |
} else {
|
201 |
+
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
202 |
}
|
203 |
break;
|
204 |
}
|
backend/modules/appointments/templates/index.php
CHANGED
@@ -60,7 +60,7 @@ use Bookly\Lib\Utils\DateTime;
|
|
60 |
data-placeholder="<?php esc_attr_e( 'Customer', 'bookly' ) ?>" <?php echo $customers === false ? 'data-ajax--action' : 'data-action' ?>="bookly_get_customers_list">
|
61 |
<?php if ( $customers !== false ) : ?>
|
62 |
<?php foreach ( $customers as $customer_id => $customer ) : ?>
|
63 |
-
<option value="<?php echo $customer_id ?>" data-search='<?php echo json_encode( array_values( $customer ) ) ?>'><?php echo esc_html( $customer['full_name'] ) ?></option>
|
64 |
<?php endforeach ?>
|
65 |
<?php endif ?>
|
66 |
</select>
|
60 |
data-placeholder="<?php esc_attr_e( 'Customer', 'bookly' ) ?>" <?php echo $customers === false ? 'data-ajax--action' : 'data-action' ?>="bookly_get_customers_list">
|
61 |
<?php if ( $customers !== false ) : ?>
|
62 |
<?php foreach ( $customers as $customer_id => $customer ) : ?>
|
63 |
+
<option value="<?php echo $customer_id ?>" data-search='<?php echo esc_attr( json_encode( array_values( $customer ) ) ) ?>'><?php echo esc_html( $customer['full_name'] ) ?></option>
|
64 |
<?php endforeach ?>
|
65 |
<?php endif ?>
|
66 |
</select>
|
backend/modules/calendar/Page.php
CHANGED
@@ -199,7 +199,7 @@ class Page extends Lib\Base\Ajax
|
|
199 |
$codes['{appointment_date}'] = Lib\Utils\DateTime::formatDate( $appointment['start_date'] );
|
200 |
$codes['{appointment_time}'] = $appointment['duration'] >= DAY_IN_SECONDS ? $appointment['start_time_info'] : Lib\Utils\DateTime::formatTime( $appointment['start_date'] );
|
201 |
$codes['{booking_number}'] = $appointment['id'];
|
202 |
-
$codes['{internal_note}'] = $appointment['internal_note'];
|
203 |
$codes['{on_waiting_list}'] = $appointment['on_waiting_list'];
|
204 |
$codes['{service_name}'] = $appointment['service_name'] ? esc_html( $appointment['service_name'] ) : __( 'Untitled', 'bookly' );
|
205 |
$codes['{service_price}'] = Lib\Utils\Price::format( $appointment['service_price'] * $appointment['units'] );
|
199 |
$codes['{appointment_date}'] = Lib\Utils\DateTime::formatDate( $appointment['start_date'] );
|
200 |
$codes['{appointment_time}'] = $appointment['duration'] >= DAY_IN_SECONDS ? $appointment['start_time_info'] : Lib\Utils\DateTime::formatTime( $appointment['start_date'] );
|
201 |
$codes['{booking_number}'] = $appointment['id'];
|
202 |
+
$codes['{internal_note}'] = esc_html( $appointment['internal_note'] );
|
203 |
$codes['{on_waiting_list}'] = $appointment['on_waiting_list'];
|
204 |
$codes['{service_name}'] = $appointment['service_name'] ? esc_html( $appointment['service_name'] ) : __( 'Untitled', 'bookly' );
|
205 |
$codes['{service_price}'] = Lib\Utils\Price::format( $appointment['service_price'] * $appointment['units'] );
|
backend/modules/calendar/resources/js/calendar.js
CHANGED
@@ -57,7 +57,7 @@ jQuery(function ($) {
|
|
57 |
staffMembers.length = 0;
|
58 |
this.booklyDropdown('getSelectedExt').forEach(function (item) {
|
59 |
ids.push(item.value);
|
60 |
-
staffMembers.push({id: item.value, name: item.name});
|
61 |
});
|
62 |
setCookie('bookly_cal_st_ids', ids);
|
63 |
if (all) {
|
@@ -87,7 +87,7 @@ jQuery(function ($) {
|
|
87 |
}
|
88 |
// Populate staffMembers.
|
89 |
$staffFilter.booklyDropdown('getSelectedExt').forEach(function (item) {
|
90 |
-
staffMembers.push({id: item.value, name: item.name});
|
91 |
$tabs.filter('[data-staff_id=' + item.value + ']').parent().show();
|
92 |
});
|
93 |
|
@@ -128,6 +128,10 @@ jQuery(function ($) {
|
|
128 |
}
|
129 |
}
|
130 |
|
|
|
|
|
|
|
|
|
131 |
$('#bookly-calendar-refresh').on('click', function () {
|
132 |
$fullCalendar.fullCalendar('refetchEvents');
|
133 |
});
|
57 |
staffMembers.length = 0;
|
58 |
this.booklyDropdown('getSelectedExt').forEach(function (item) {
|
59 |
ids.push(item.value);
|
60 |
+
staffMembers.push({id: item.value, name: encodeHTML(item.name)});
|
61 |
});
|
62 |
setCookie('bookly_cal_st_ids', ids);
|
63 |
if (all) {
|
87 |
}
|
88 |
// Populate staffMembers.
|
89 |
$staffFilter.booklyDropdown('getSelectedExt').forEach(function (item) {
|
90 |
+
staffMembers.push({id: item.value, name: encodeHTML(item.name)});
|
91 |
$tabs.filter('[data-staff_id=' + item.value + ']').parent().show();
|
92 |
});
|
93 |
|
128 |
}
|
129 |
}
|
130 |
|
131 |
+
function encodeHTML(s) {
|
132 |
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
133 |
+
}
|
134 |
+
|
135 |
$('#bookly-calendar-refresh').on('click', function () {
|
136 |
$fullCalendar.fullCalendar('refetchEvents');
|
137 |
});
|
backend/modules/customers/resources/js/customers.js
CHANGED
@@ -27,7 +27,7 @@ jQuery(function($) {
|
|
27 |
case 'total_appointments':
|
28 |
case 'payments':
|
29 |
case 'wp_user':
|
30 |
-
columns.push({data: column});
|
31 |
break;
|
32 |
case 'address':
|
33 |
columns.push({data: column, render: $.fn.dataTable.render.text(), orderable: false});
|
@@ -166,7 +166,7 @@ jQuery(function($) {
|
|
166 |
address: '',
|
167 |
info_fields: {},
|
168 |
notes: '',
|
169 |
-
birthday:
|
170 |
};
|
171 |
BooklyL10n.infoFields.forEach(function (field) {
|
172 |
customer.info_fields[field.id] = {id: field.id, value: field.type === 'checkboxes' ? [] : ''};
|
27 |
case 'total_appointments':
|
28 |
case 'payments':
|
29 |
case 'wp_user':
|
30 |
+
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
31 |
break;
|
32 |
case 'address':
|
33 |
columns.push({data: column, render: $.fn.dataTable.render.text(), orderable: false});
|
166 |
address: '',
|
167 |
info_fields: {},
|
168 |
notes: '',
|
169 |
+
birthday: null
|
170 |
};
|
171 |
BooklyL10n.infoFields.forEach(function (field) {
|
172 |
customer.info_fields[field.id] = {id: field.id, value: field.type === 'checkboxes' ? [] : ''};
|
backend/modules/customers/templates/index.php
CHANGED
@@ -18,7 +18,7 @@ use Bookly\Backend\Modules\Customers\Proxy;
|
|
18 |
<div class="row">
|
19 |
<div class="col-md-4">
|
20 |
<div class="form-group">
|
21 |
-
<input class="form-control" type="text" id="bookly-filter" placeholder="<?php esc_attr_e( 'Quick search
|
22 |
</div>
|
23 |
</div>
|
24 |
<div class="col-md-8 form-row justify-content-end pr-0">
|
18 |
<div class="row">
|
19 |
<div class="col-md-4">
|
20 |
<div class="form-group">
|
21 |
+
<input class="form-control" type="text" id="bookly-filter" placeholder="<?php esc_attr_e( 'Quick search customers', 'bookly' ) ?>"/>
|
22 |
</div>
|
23 |
</div>
|
24 |
<div class="col-md-8 form-row justify-content-end pr-0">
|
backend/modules/payments/resources/js/payments.js
CHANGED
@@ -137,7 +137,7 @@ jQuery(function($) {
|
|
137 |
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
138 |
break;
|
139 |
default:
|
140 |
-
columns.push({data: column});
|
141 |
break;
|
142 |
}
|
143 |
}
|
137 |
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
138 |
break;
|
139 |
default:
|
140 |
+
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
141 |
break;
|
142 |
}
|
143 |
}
|
backend/modules/payments/templates/index.php
CHANGED
@@ -46,7 +46,7 @@ use Bookly\Backend\Components\Controls;
|
|
46 |
<select class="form-control <?php echo $customers === false ? 'bookly-js-select-ajax' : 'bookly-js-select' ?>" id="bookly-filter-customer" data-placeholder="<?php esc_attr_e( 'Customer', 'bookly' ) ?>" <?php echo $customers === false ? 'data-ajax--action' : 'data-action' ?>="bookly_get_customers_list">
|
47 |
<?php if ( $customers !== false ) : ?>
|
48 |
<?php foreach ( $customers as $customer_id => $customer ) : ?>
|
49 |
-
<option value="<?php echo $customer_id ?>" data-search='<?php echo json_encode( array_values( $customer ) ) ?>'><?php echo esc_html( $customer['full_name'] ) ?></option>
|
50 |
<?php endforeach ?>
|
51 |
<?php endif ?>
|
52 |
</select>
|
46 |
<select class="form-control <?php echo $customers === false ? 'bookly-js-select-ajax' : 'bookly-js-select' ?>" id="bookly-filter-customer" data-placeholder="<?php esc_attr_e( 'Customer', 'bookly' ) ?>" <?php echo $customers === false ? 'data-ajax--action' : 'data-action' ?>="bookly_get_customers_list">
|
47 |
<?php if ( $customers !== false ) : ?>
|
48 |
<?php foreach ( $customers as $customer_id => $customer ) : ?>
|
49 |
+
<option value="<?php echo $customer_id ?>" data-search='<?php echo esc_attr( json_encode( array_values( $customer ) ) ) ?>'><?php echo esc_html( $customer['full_name'] ) ?></option>
|
50 |
<?php endforeach ?>
|
51 |
<?php endif ?>
|
52 |
</select>
|
backend/modules/services/resources/js/services-list.js
CHANGED
@@ -85,13 +85,13 @@ jQuery(function ($) {
|
|
85 |
});
|
86 |
break;
|
87 |
default:
|
88 |
-
columns.push({data: column});
|
89 |
break;
|
90 |
}
|
91 |
}
|
92 |
});
|
93 |
columns.push({
|
94 |
-
responsivePriority:
|
95 |
orderable: false,
|
96 |
searchable: false,
|
97 |
render: function (data, type, row, meta) {
|
@@ -235,7 +235,8 @@ jQuery(function ($) {
|
|
235 |
$servicesList.on('click', '[data-action="duplicate"]', function () {
|
236 |
if (confirm(BooklyL10n.are_you_sure + "\n\n" + BooklyL10n.private_warning)) {
|
237 |
let ladda = rangeTools.ladda(this),
|
238 |
-
|
|
|
239 |
$.post(
|
240 |
ajaxurl,
|
241 |
{
|
85 |
});
|
86 |
break;
|
87 |
default:
|
88 |
+
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
89 |
break;
|
90 |
}
|
91 |
}
|
92 |
});
|
93 |
columns.push({
|
94 |
+
responsivePriority: 2,
|
95 |
orderable: false,
|
96 |
searchable: false,
|
97 |
render: function (data, type, row, meta) {
|
235 |
$servicesList.on('click', '[data-action="duplicate"]', function () {
|
236 |
if (confirm(BooklyL10n.are_you_sure + "\n\n" + BooklyL10n.private_warning)) {
|
237 |
let ladda = rangeTools.ladda(this),
|
238 |
+
$tr = $(this).closest('tr'),
|
239 |
+
data = $servicesList.DataTable().row($tr.hasClass('child') ? $tr.prev() : $tr).data();
|
240 |
$.post(
|
241 |
ajaxurl,
|
242 |
{
|
backend/modules/staff/resources/js/staff-list.js
CHANGED
@@ -49,7 +49,7 @@ jQuery(function ($) {
|
|
49 |
});
|
50 |
break;
|
51 |
default:
|
52 |
-
columns.push({data: column});
|
53 |
break;
|
54 |
}
|
55 |
}
|
49 |
});
|
50 |
break;
|
51 |
default:
|
52 |
+
columns.push({data: column, render: $.fn.dataTable.render.text()});
|
53 |
break;
|
54 |
}
|
55 |
}
|
frontend/components/booking/InfoText.php
CHANGED
@@ -91,8 +91,8 @@ class InfoText
|
|
91 |
$staff = Lib\Entities\Staff::find( $staff_ids[0] );
|
92 |
}
|
93 |
if ( $staff ) {
|
94 |
-
$data['staff_names'][] = $staff->getTranslatedName();
|
95 |
-
$data['staff_info'][] = $staff->getTranslatedInfo();
|
96 |
if ( $staff->getAttachmentId() && $img = wp_get_attachment_image_src( $staff->getAttachmentId(), 'full' ) ) {
|
97 |
$staff_photo = '<img src="' . $img[0] . '"/>';
|
98 |
}
|
@@ -198,8 +198,8 @@ class InfoText
|
|
198 |
}
|
199 |
// For Task when time step can be skipped, staff can be false
|
200 |
$staff = $cart_item->getStaff();
|
201 |
-
$data['staff_info'][] = $staff ? $staff->getTranslatedInfo() : '';
|
202 |
-
$data['staff_name'][] = $staff ? $staff->getTranslatedName() : '';
|
203 |
if ( $staff && $staff->getAttachmentId() && $img = wp_get_attachment_image_src( $staff->getAttachmentId(), 'full' ) ) {
|
204 |
$data['staff_photo'][] = '<img src="' . $img[0] . '"/>';
|
205 |
} else {
|
91 |
$staff = Lib\Entities\Staff::find( $staff_ids[0] );
|
92 |
}
|
93 |
if ( $staff ) {
|
94 |
+
$data['staff_names'][] = esc_html( $staff->getTranslatedName() );
|
95 |
+
$data['staff_info'][] = esc_html( $staff->getTranslatedInfo() );
|
96 |
if ( $staff->getAttachmentId() && $img = wp_get_attachment_image_src( $staff->getAttachmentId(), 'full' ) ) {
|
97 |
$staff_photo = '<img src="' . $img[0] . '"/>';
|
98 |
}
|
198 |
}
|
199 |
// For Task when time step can be skipped, staff can be false
|
200 |
$staff = $cart_item->getStaff();
|
201 |
+
$data['staff_info'][] = $staff ? esc_html( $staff->getTranslatedInfo() ) : '';
|
202 |
+
$data['staff_name'][] = $staff ? esc_html( $staff->getTranslatedName() ) : '';
|
203 |
if ( $staff && $staff->getAttachmentId() && $img = wp_get_attachment_image_src( $staff->getAttachmentId(), 'full' ) ) {
|
204 |
$data['staff_photo'][] = '<img src="' . $img[0] . '"/>';
|
205 |
} else {
|
lib/CartItem.php
CHANGED
@@ -124,30 +124,30 @@ class CartItem
|
|
124 |
static $service_prices_cache = array();
|
125 |
|
126 |
$service = $this->getService();
|
127 |
-
|
128 |
-
|
129 |
-
if ( Config::specialHoursActive() ) {
|
130 |
-
$service_start = date( 'H:i:s', strtotime( $this->slots[0][2] ) );
|
131 |
} else {
|
132 |
-
|
133 |
-
}
|
134 |
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
|
|
|
|
140 |
} else {
|
141 |
$staff_service = new Entities\StaffService();
|
142 |
-
$location_id
|
143 |
$staff_service->loadBy( compact( 'staff_id', 'service_id', 'location_id' ) );
|
144 |
if ( ! $staff_service->isLoaded() ) {
|
145 |
$staff_service->loadBy( array( 'staff_id' => $staff_id, 'service_id' => $service_id, 'location_id' => null ) );
|
146 |
}
|
147 |
$service_price = $staff_service->getPrice() * $this->getUnits();
|
148 |
$service_price = Proxy\SpecialHours::adjustPrice( $service_price, $staff_id, $service_id, $location_id, $service_start, $this->getUnits() );
|
|
|
149 |
}
|
150 |
-
|
151 |
}
|
152 |
|
153 |
return $service_price;
|
124 |
static $service_prices_cache = array();
|
125 |
|
126 |
$service = $this->getService();
|
127 |
+
if ( $service->withSubServices() ) {
|
128 |
+
$service_price = $service->getPrice();
|
|
|
|
|
129 |
} else {
|
130 |
+
list ( $service_id, $staff_id, , $location_id ) = $this->slots[0];
|
|
|
131 |
|
132 |
+
if ( Config::specialHoursActive() ) {
|
133 |
+
$service_start = date( 'H:i:s', strtotime( $this->slots[0][2] ) );
|
134 |
+
} else {
|
135 |
+
$service_start = 'unused'; //the price is the same for all services in day
|
136 |
+
}
|
137 |
+
if ( isset ( $service_prices_cache[ $staff_id ][ $service_id ][ $location_id ][ $service_start ] ) ) {
|
138 |
+
$service_price = $service_prices_cache[ $staff_id ][ $service_id ][ $location_id ][ $service_start ];
|
139 |
} else {
|
140 |
$staff_service = new Entities\StaffService();
|
141 |
+
$location_id = Proxy\Locations::prepareStaffLocationId( $location_id, $staff_id ) ?: null;
|
142 |
$staff_service->loadBy( compact( 'staff_id', 'service_id', 'location_id' ) );
|
143 |
if ( ! $staff_service->isLoaded() ) {
|
144 |
$staff_service->loadBy( array( 'staff_id' => $staff_id, 'service_id' => $service_id, 'location_id' => null ) );
|
145 |
}
|
146 |
$service_price = $staff_service->getPrice() * $this->getUnits();
|
147 |
$service_price = Proxy\SpecialHours::adjustPrice( $service_price, $staff_id, $service_id, $location_id, $service_start, $this->getUnits() );
|
148 |
+
$service_prices_cache[ $staff_id ][ $service_id ][ $location_id ][ $service_start ] = $service_price;
|
149 |
}
|
150 |
+
|
151 |
}
|
152 |
|
153 |
return $service_price;
|
lib/Updater.php
CHANGED
@@ -16,21 +16,21 @@ class Updater extends Base\Updater
|
|
16 |
|
17 |
function update_18_3()
|
18 |
{
|
19 |
-
$
|
20 |
-
|
|
|
21 |
'bookly_payments' => array(
|
22 |
'ALTER TABLE `%s` ADD COLUMN `token` VARCHAR(255) DEFAULT NULL AFTER `status`',
|
23 |
),
|
24 |
) );
|
25 |
-
});
|
26 |
-
|
27 |
|
28 |
-
$disposable_options[] = $this->disposable( __FUNCTION__ . '-add-tokens-2', function () {
|
29 |
/** @global \wpdb $wpdb */
|
30 |
global $wpdb;
|
31 |
|
32 |
// Setup tokens for existing payments
|
33 |
-
$payments_table = $
|
34 |
|
35 |
foreach ( $wpdb->get_results( 'SELECT id FROM `' . $payments_table . '` WHERE token IS NULL' ) as $record ) {
|
36 |
$wpdb->query( $wpdb->prepare( 'UPDATE `' . $payments_table . '` SET `token` = %s WHERE id = %d', Utils\Common::generateToken( 'Bookly\Lib\Entities\Payment', 'token' ), $record->id ) );
|
16 |
|
17 |
function update_18_3()
|
18 |
{
|
19 |
+
$self = $this;
|
20 |
+
$disposable_options[] = $this->disposable( __FUNCTION__ . '-add-tokens-1', function () use ( $self ) {
|
21 |
+
$self->alterTables( array(
|
22 |
'bookly_payments' => array(
|
23 |
'ALTER TABLE `%s` ADD COLUMN `token` VARCHAR(255) DEFAULT NULL AFTER `status`',
|
24 |
),
|
25 |
) );
|
26 |
+
} );
|
|
|
27 |
|
28 |
+
$disposable_options[] = $this->disposable( __FUNCTION__ . '-add-tokens-2', function () use ( $self ) {
|
29 |
/** @global \wpdb $wpdb */
|
30 |
global $wpdb;
|
31 |
|
32 |
// Setup tokens for existing payments
|
33 |
+
$payments_table = $self->getTableName( 'bookly_payments' );
|
34 |
|
35 |
foreach ( $wpdb->get_results( 'SELECT id FROM `' . $payments_table . '` WHERE token IS NULL' ) as $record ) {
|
36 |
$wpdb->query( $wpdb->prepare( 'UPDATE `' . $payments_table . '` SET `token` = %s WHERE id = %d', Utils\Common::generateToken( 'Bookly\Lib\Entities\Payment', 'token' ), $record->id ) );
|
lib/entities/Service.php
CHANGED
@@ -274,6 +274,7 @@ class Service extends Lib\Base\Entity
|
|
274 |
break;
|
275 |
default:
|
276 |
foreach ( $appointment_dates as $appointment_date ) {
|
|
|
277 |
switch ( $this->getLimitPeriod() ) {
|
278 |
case 'calendar_day':
|
279 |
$bound_start = date_create( $appointment_date )->format( 'Y-m-d 00:00:00' );
|
@@ -295,32 +296,45 @@ class Service extends Lib\Base\Entity
|
|
295 |
$bound_start = date_create( $appointment_date )->modify( 'first day of January' )->format( 'Y-m-d 00:00:00' );
|
296 |
$bound_end = date_create( $appointment_date )->modify( 'last day of December' )->format( 'Y-m-d 23:59:59' );
|
297 |
break;
|
|
|
298 |
case 'day':
|
299 |
$bound_start = date_create( $appointment_date )->modify( '-1 day' )->format( 'Y-m-d H:i:s' );
|
300 |
$bound_end = $appointment_date;
|
|
|
301 |
break;
|
302 |
case 'week':
|
303 |
$bound_start = date_create( $appointment_date )->modify( '-1 week' )->format( 'Y-m-d H:i:s' );
|
304 |
$bound_end = $appointment_date;
|
|
|
305 |
break;
|
306 |
case 'month':
|
307 |
$bound_start = date_create( $appointment_date )->modify( '-30 days' )->format( 'Y-m-d H:i:s' );
|
308 |
$bound_end = $appointment_date;
|
|
|
309 |
break;
|
310 |
case 'year':
|
311 |
$bound_start = date_create( $appointment_date )->modify( '-365 days' )->format( 'Y-m-d H:i:s' );
|
312 |
$bound_end = $appointment_date;
|
|
|
313 |
break;
|
314 |
}
|
315 |
-
$
|
316 |
->leftJoin( 'Appointment', 'a', 'ca.appointment_id = a.id' )
|
317 |
->where( 'a.service_id', $service_id )
|
318 |
->where( 'ca.compound_service_id', $compound_service_id )
|
319 |
->where( 'ca.customer_id', $customer_id )
|
320 |
-
->
|
321 |
-
|
322 |
-
|
323 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
$cart_count = 0;
|
325 |
$bound_start = strtotime( $bound_start );
|
326 |
$bound_end = strtotime( $bound_end );
|
274 |
break;
|
275 |
default:
|
276 |
foreach ( $appointment_dates as $appointment_date ) {
|
277 |
+
$regarding_appointment = false;
|
278 |
switch ( $this->getLimitPeriod() ) {
|
279 |
case 'calendar_day':
|
280 |
$bound_start = date_create( $appointment_date )->format( 'Y-m-d 00:00:00' );
|
296 |
$bound_start = date_create( $appointment_date )->modify( 'first day of January' )->format( 'Y-m-d 00:00:00' );
|
297 |
$bound_end = date_create( $appointment_date )->modify( 'last day of December' )->format( 'Y-m-d 23:59:59' );
|
298 |
break;
|
299 |
+
|
300 |
case 'day':
|
301 |
$bound_start = date_create( $appointment_date )->modify( '-1 day' )->format( 'Y-m-d H:i:s' );
|
302 |
$bound_end = $appointment_date;
|
303 |
+
$regarding_appointment = true;
|
304 |
break;
|
305 |
case 'week':
|
306 |
$bound_start = date_create( $appointment_date )->modify( '-1 week' )->format( 'Y-m-d H:i:s' );
|
307 |
$bound_end = $appointment_date;
|
308 |
+
$regarding_appointment = true;
|
309 |
break;
|
310 |
case 'month':
|
311 |
$bound_start = date_create( $appointment_date )->modify( '-30 days' )->format( 'Y-m-d H:i:s' );
|
312 |
$bound_end = $appointment_date;
|
313 |
+
$regarding_appointment = true;
|
314 |
break;
|
315 |
case 'year':
|
316 |
$bound_start = date_create( $appointment_date )->modify( '-365 days' )->format( 'Y-m-d H:i:s' );
|
317 |
$bound_end = $appointment_date;
|
318 |
+
$regarding_appointment = true;
|
319 |
break;
|
320 |
}
|
321 |
+
$query = CustomerAppointment::query( 'ca' )
|
322 |
->leftJoin( 'Appointment', 'a', 'ca.appointment_id = a.id' )
|
323 |
->where( 'a.service_id', $service_id )
|
324 |
->where( 'ca.compound_service_id', $compound_service_id )
|
325 |
->where( 'ca.customer_id', $customer_id )
|
326 |
+
->whereNot( 'ca.status', CustomerAppointment::STATUS_WAITLISTED );
|
327 |
+
if ( $regarding_appointment ) {
|
328 |
+
$query
|
329 |
+
->whereGt( 'a.start_date', $bound_start )
|
330 |
+
->whereLte( 'a.start_date', $bound_end );
|
331 |
+
} else {
|
332 |
+
$query
|
333 |
+
->whereGte( 'a.start_date', $bound_start )
|
334 |
+
->whereLt( 'a.start_date', $bound_end );
|
335 |
+
}
|
336 |
+
|
337 |
+
$db_count = $query->count();
|
338 |
$cart_count = 0;
|
339 |
$bound_start = strtotime( $bound_start );
|
340 |
$bound_end = strtotime( $bound_end );
|
main.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Bookly
|
4 |
Plugin URI: https://www.booking-wp-plugin.com/?utm_source=bookly_admin&utm_medium=plugins_page&utm_campaign=plugins_page
|
5 |
Description: Bookly Plugin – is a great easy-to-use and easy-to-manage booking tool for service providers who think about their customers. The plugin supports a wide range of services provided by business and individuals who offer reservations through websites. Set up any reservation quickly, pleasantly and easily with Bookly!
|
6 |
-
Version: 18.
|
7 |
Author: Bookly
|
8 |
Author URI: https://www.booking-wp-plugin.com/?utm_source=bookly_admin&utm_medium=plugins_page&utm_campaign=plugins_page
|
9 |
Text Domain: bookly
|
3 |
Plugin Name: Bookly
|
4 |
Plugin URI: https://www.booking-wp-plugin.com/?utm_source=bookly_admin&utm_medium=plugins_page&utm_campaign=plugins_page
|
5 |
Description: Bookly Plugin – is a great easy-to-use and easy-to-manage booking tool for service providers who think about their customers. The plugin supports a wide range of services provided by business and individuals who offer reservations through websites. Set up any reservation quickly, pleasantly and easily with Bookly!
|
6 |
+
Version: 18.5
|
7 |
Author: Bookly
|
8 |
Author URI: https://www.booking-wp-plugin.com/?utm_source=bookly_admin&utm_medium=plugins_page&utm_campaign=plugins_page
|
9 |
Text Domain: bookly
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Donate link: https://www.booking-wp-plugin.com/
|
|
5 |
Requires at least: 3.7
|
6 |
Tested up to: 5.4.2
|
7 |
Requires PHP: 5.3.7
|
8 |
-
Stable tag: 18.
|
9 |
License: GPLv3
|
10 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
@@ -13,7 +13,7 @@ Bookly is a booking plugin for WordPress for building an advanced automated onli
|
|
13 |
|
14 |
== Description ==
|
15 |
|
16 |
-
**Bookly** is a free **scheduling plugin for WordPress** that allows accepting **online bookings** on your website and automating your **reservation system**. Manage your **booking calendar**, services, client base, save time and money – all in one place. Join more than
|
17 |
|
18 |
https://youtu.be/XkCrADjLt2s
|
19 |
|
5 |
Requires at least: 3.7
|
6 |
Tested up to: 5.4.2
|
7 |
Requires PHP: 5.3.7
|
8 |
+
Stable tag: 18.5
|
9 |
License: GPLv3
|
10 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
13 |
|
14 |
== Description ==
|
15 |
|
16 |
+
**Bookly** is a free **scheduling plugin for WordPress** that allows accepting **online bookings** on your website and automating your **reservation system**. Manage your **booking calendar**, services, client base, save time and money – all in one place. Join more than 40,000 businesses all around the world that have already automated their **online booking system**!
|
17 |
|
18 |
https://youtu.be/XkCrADjLt2s
|
19 |
|