WordPress Online Booking and Scheduling Plugin – Bookly - Version 13.1

Version Description

  • Added support for WordPress 4.8.2
Download this release

Release Info

Developer Ladela
Plugin Icon 128x128 WordPress Online Booking and Scheduling Plugin – Bookly
Version 13.1
Comparing to
See all releases

Code changes from version 13.0 to 13.1

backend/modules/debug/Controller.php CHANGED
@@ -31,48 +31,45 @@ class Controller extends Lib\Base\Controller
31
  ) );
32
 
33
  $debug = array();
34
- /** @var Lib\Base\Plugin $plugin */
35
- foreach ( apply_filters( 'bookly_plugins', array() ) as $plugin ) {
36
- foreach ( $plugin::getEntityClasses() as $entity_class ) {
37
- $tableName = $entity_class::getTableName();
38
- $debug[ $tableName ] = array(
39
- 'fields' => null,
40
- 'constraints' => null,
41
- 'status' => null,
42
- );
43
- if ( $this->_tableExists( $tableName ) ) {
44
- $tableStructure = $this->_getTableStructure( $tableName );
45
- $tableConstraints = $this->_getTableConstraints( $tableName );
46
- $entitySchema = $entity_class::getSchema();
47
- $entityConstraints = $entity_class::getConstraints();
48
- $debug[ $tableName ]['status'] = self::TABLE_STATUS_OK;
49
- $debug[ $tableName ]['fields'] = array();
50
-
51
- // Comparing model schema with real DB schema
52
- foreach ( $entitySchema as $field => $data ) {
53
- if ( in_array( $field, $tableStructure ) ) {
54
- $debug[ $tableName ]['fields'][ $field ] = 1;
55
- } else {
56
- $debug[ $tableName ]['fields'][ $field ] = 0;
57
- $debug[ $tableName ]['status'] = self::TABLE_STATUS_WARNING;
58
- }
59
  }
 
60
 
61
- // Comparing model constraints with real DB constraints
62
- foreach ( $entityConstraints as $constraint ) {
63
- $key = $constraint['column_name'] . $constraint['referenced_table_name'] . $constraint['referenced_column_name'];
64
- $debug[ $tableName ]['constraints'][ $key ] = $constraint;
65
- if ( array_key_exists ( $key, $tableConstraints ) ) {
66
- $debug[ $tableName ]['constraints'][ $key ]['status'] = 1;
67
- } else {
68
- $debug[ $tableName ]['constraints'][ $key ]['status'] = 0;
69
- $debug[ $tableName ]['status'] = self::TABLE_STATUS_WARNING;
70
- }
71
  }
72
-
73
- } else {
74
- $debug[ $tableName ]['status'] = self::TABLE_STATUS_ERROR;
75
  }
 
 
 
76
  }
77
  }
78
 
@@ -90,33 +87,30 @@ class Controller extends Lib\Base\Controller
90
 
91
  $result = array();
92
 
93
- foreach ( apply_filters( 'bookly_plugins', array() ) as $plugin ) {
94
- /** @var Lib\Base\Plugin $plugin */
95
- $installer_class = $plugin::getRootNamespace() . '\Lib\Installer';
96
- /** @var Lib\Base\Installer $installer */
97
- $installer = new $installer_class();
98
-
99
- foreach ( $plugin::getEntityClasses() as $entity_class ) {
100
- $table_name = $entity_class::getTableName();
101
- $result['entities'][ $entity_class ] = array(
102
- 'fields' => $this->_getTableStructure( $table_name ),
103
- 'values' => $wpdb->get_results( 'SELECT * FROM ' . $table_name, ARRAY_N )
104
- );
105
- }
106
- $plugin_prefix = $plugin::getPrefix();
107
- $options_postfix = array( 'data_loaded', 'grace_start', 'db_version', 'installation_time' );
108
- if ( $plugin_prefix != 'bookly_' ) {
109
- $options_postfix[] = 'enabled';
110
- }
111
- foreach ( $options_postfix as $option ) {
112
- $option_name = $plugin_prefix . $option;
113
- $result['options'][ $option_name ] = get_option( $option_name );
114
- }
115
 
116
- $result['options'][ $plugin::getPurchaseCodeOption() ] = $plugin::getPurchaseCode();
117
- foreach ( $installer->getOptions() as $option_name => $option_value ) {
118
- $result['options'][ $option_name ] = get_option( $option_name );
119
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
 
122
  header( 'Content-type: application/json' );
@@ -136,77 +130,74 @@ class Controller extends Lib\Base\Controller
136
 
137
  if ( $file = $_FILES['import']['name'] ) {
138
  $json = file_get_contents( $_FILES['import']['tmp_name'] );
139
- if ( $json !== false) {
140
  $wpdb->query( 'SET FOREIGN_KEY_CHECKS = 0' );
141
 
142
  $data = json_decode( $json, true );
143
 
144
- foreach ( apply_filters( 'bookly_plugins', array() ) as $plugin ) {
145
- /** @var Lib\Base\Plugin $plugin */
146
- $installer_class = $plugin::getRootNamespace() . '\Lib\Installer';
147
- /** @var Lib\Base\Installer $installer */
148
- $installer = new $installer_class();
149
-
150
- // Drop all data and options.
151
- $installer->removeData();
152
- $installer->dropTables();
153
- $installer->createTables();
154
-
155
- // Insert tables data.
156
- foreach ( $plugin::getEntityClasses() as $entity_class ) {
157
- if ( isset ( $data['entities'][ $entity_class ]['values'][0] ) ) {
158
- $table_name = $entity_class::getTableName();
159
- $query = sprintf(
160
- 'INSERT INTO `%s` (`%s`) VALUES (%%s)',
161
- $table_name,
162
- implode( '`,`', $data['entities'][ $entity_class ]['fields'] )
163
- );
164
- $placeholders = array();
165
- $values = array();
166
- $counter = 0;
167
- foreach ( $data['entities'][ $entity_class ]['values'] as $row ) {
168
- $params = array();
169
- foreach ( $row as $value ) {
170
- if ( $value === null ) {
171
- $params[] = 'NULL';
172
- } else {
173
- $params[] = '%s';
174
- $values[] = $value;
175
- }
176
- }
177
- $placeholders[] = implode( ',', $params );
178
- if ( ++ $counter > 50 ) {
179
- // Flush.
180
- $wpdb->query( $wpdb->prepare( sprintf( $query, implode( '),(', $placeholders ) ), $values ) );
181
- $placeholders = array();
182
- $values = array();
183
- $counter = 0;
184
  }
185
  }
186
- if ( ! empty ( $placeholders ) ) {
 
 
187
  $wpdb->query( $wpdb->prepare( sprintf( $query, implode( '),(', $placeholders ) ), $values ) );
 
 
 
188
  }
189
  }
 
 
 
190
  }
 
191
 
192
- // Insert options data.
193
- foreach ( $installer->getOptions() as $option_name => $option_value ) {
194
- add_option( $option_name, $data['options'][ $option_name ] );
195
- }
196
-
197
- $plugin_prefix = $plugin::getPrefix();
198
- $options_postfix = array( 'data_loaded', 'grace_start', 'db_version' );
199
- if ( $plugin_prefix != 'bookly_' ) {
200
- $options_postfix[] = 'enabled';
201
- }
202
- foreach ( $options_postfix as $option ) {
203
- $option_name = $plugin_prefix . $option;
204
- add_option( $option_name, $data['options'][ $option_name ] );
205
- }
206
  }
207
 
208
- header( 'Location: ' . admin_url( 'admin.php?page=bookly-debug&status=imported' ) );
 
 
 
 
 
 
 
 
209
  }
 
 
210
  }
211
 
212
  header( 'Location: ' . admin_url( 'admin.php?page=bookly-debug' ) );
31
  ) );
32
 
33
  $debug = array();
34
+ foreach ( Lib\Plugin::getEntityClasses() as $entity_class ) {
35
+ $tableName = $entity_class::getTableName();
36
+ $debug[ $tableName ] = array(
37
+ 'fields' => null,
38
+ 'constraints' => null,
39
+ 'status' => null,
40
+ );
41
+ if ( $this->_tableExists( $tableName ) ) {
42
+ $tableStructure = $this->_getTableStructure( $tableName );
43
+ $tableConstraints = $this->_getTableConstraints( $tableName );
44
+ $entitySchema = $entity_class::getSchema();
45
+ $entityConstraints = $entity_class::getConstraints();
46
+ $debug[ $tableName ]['status'] = self::TABLE_STATUS_OK;
47
+ $debug[ $tableName ]['fields'] = array();
48
+
49
+ // Comparing model schema with real DB schema
50
+ foreach ( $entitySchema as $field => $data ) {
51
+ if ( in_array( $field, $tableStructure ) ) {
52
+ $debug[ $tableName ]['fields'][ $field ] = 1;
53
+ } else {
54
+ $debug[ $tableName ]['fields'][ $field ] = 0;
55
+ $debug[ $tableName ]['status'] = self::TABLE_STATUS_WARNING;
 
 
 
56
  }
57
+ }
58
 
59
+ // Comparing model constraints with real DB constraints
60
+ foreach ( $entityConstraints as $constraint ) {
61
+ $key = $constraint['column_name'] . $constraint['referenced_table_name'] . $constraint['referenced_column_name'];
62
+ $debug[ $tableName ]['constraints'][ $key ] = $constraint;
63
+ if ( array_key_exists ( $key, $tableConstraints ) ) {
64
+ $debug[ $tableName ]['constraints'][ $key ]['status'] = 1;
65
+ } else {
66
+ $debug[ $tableName ]['constraints'][ $key ]['status'] = 0;
67
+ $debug[ $tableName ]['status'] = self::TABLE_STATUS_WARNING;
 
68
  }
 
 
 
69
  }
70
+
71
+ } else {
72
+ $debug[ $tableName ]['status'] = self::TABLE_STATUS_ERROR;
73
  }
74
  }
75
 
87
 
88
  $result = array();
89
 
90
+ $installer_class = Lib\Plugin::getRootNamespace() . '\Lib\Installer';
91
+ /** @var Lib\Base\Installer $installer */
92
+ $installer = new $installer_class();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
+ foreach ( Lib\Plugin::getEntityClasses() as $entity_class ) {
95
+ $table_name = $entity_class::getTableName();
96
+ $result['entities'][ $entity_class ] = array(
97
+ 'fields' => $this->_getTableStructure( $table_name ),
98
+ 'values' => $wpdb->get_results( 'SELECT * FROM ' . $table_name, ARRAY_N )
99
+ );
100
+ }
101
+ $plugin_prefix = Lib\Plugin::getPrefix();
102
+ $options_postfix = array( 'data_loaded', 'grace_start', 'db_version', 'installation_time' );
103
+ if ( $plugin_prefix != 'bookly_' ) {
104
+ $options_postfix[] = 'enabled';
105
+ }
106
+ foreach ( $options_postfix as $option ) {
107
+ $option_name = $plugin_prefix . $option;
108
+ $result['options'][ $option_name ] = get_option( $option_name );
109
+ }
110
+
111
+ $result['options'][ Lib\Plugin::getPurchaseCodeOption() ] = Lib\Plugin::getPurchaseCode();
112
+ foreach ( $installer->getOptions() as $option_name => $option_value ) {
113
+ $result['options'][ $option_name ] = get_option( $option_name );
114
  }
115
 
116
  header( 'Content-type: application/json' );
130
 
131
  if ( $file = $_FILES['import']['name'] ) {
132
  $json = file_get_contents( $_FILES['import']['tmp_name'] );
133
+ if ( $json !== false ) {
134
  $wpdb->query( 'SET FOREIGN_KEY_CHECKS = 0' );
135
 
136
  $data = json_decode( $json, true );
137
 
138
+ $installer_class = Lib\Plugin::getRootNamespace() . '\Lib\Installer';
139
+ /** @var Lib\Base\Installer $installer */
140
+ $installer = new $installer_class();
141
+
142
+ // Drop all data and options.
143
+ $installer->removeData();
144
+ $installer->dropTables();
145
+ $installer->createTables();
146
+
147
+ // Insert tables data.
148
+ foreach ( Lib\Plugin::getEntityClasses() as $entity_class ) {
149
+ if ( isset ( $data['entities'][ $entity_class ]['values'][0] ) ) {
150
+ $table_name = $entity_class::getTableName();
151
+ $query = sprintf(
152
+ 'INSERT INTO `%s` (`%s`) VALUES (%%s)',
153
+ $table_name,
154
+ implode( '`,`', $data['entities'][ $entity_class ]['fields'] )
155
+ );
156
+ $placeholders = array();
157
+ $values = array();
158
+ $counter = 0;
159
+ foreach ( $data['entities'][ $entity_class ]['values'] as $row ) {
160
+ $params = array();
161
+ foreach ( $row as $value ) {
162
+ if ( $value === null ) {
163
+ $params[] = 'NULL';
164
+ } else {
165
+ $params[] = '%s';
166
+ $values[] = $value;
 
 
 
 
 
 
 
 
 
 
 
167
  }
168
  }
169
+ $placeholders[] = implode( ',', $params );
170
+ if ( ++ $counter > 50 ) {
171
+ // Flush.
172
  $wpdb->query( $wpdb->prepare( sprintf( $query, implode( '),(', $placeholders ) ), $values ) );
173
+ $placeholders = array();
174
+ $values = array();
175
+ $counter = 0;
176
  }
177
  }
178
+ if ( ! empty ( $placeholders ) ) {
179
+ $wpdb->query( $wpdb->prepare( sprintf( $query, implode( '),(', $placeholders ) ), $values ) );
180
+ }
181
  }
182
+ }
183
 
184
+ // Insert options data.
185
+ foreach ( $installer->getOptions() as $option_name => $option_value ) {
186
+ add_option( $option_name, $data['options'][ $option_name ] );
 
 
 
 
 
 
 
 
 
 
 
187
  }
188
 
189
+ $plugin_prefix = Lib\Plugin::getPrefix();
190
+ $options_postfix = array( 'data_loaded', 'grace_start', 'db_version' );
191
+ if ( $plugin_prefix != 'bookly_' ) {
192
+ $options_postfix[] = 'enabled';
193
+ }
194
+ foreach ( $options_postfix as $option ) {
195
+ $option_name = $plugin_prefix . $option;
196
+ add_option( $option_name, $data['options'][ $option_name ] );
197
+ }
198
  }
199
+
200
+ header( 'Location: ' . admin_url( 'admin.php?page=bookly-debug&status=imported' ) );
201
  }
202
 
203
  header( 'Location: ' . admin_url( 'admin.php?page=bookly-debug' ) );
backend/modules/support/Controller.php CHANGED
@@ -29,8 +29,7 @@ class Controller extends Lib\Base\Controller
29
  ) );
30
  }
31
 
32
- $plugins = apply_filters( 'bookly_plugins', array() );
33
- $message = $this->render( '_email_to_support', compact( 'name', 'email', 'msg', 'plugins' ), false );
34
  $headers = array(
35
  'Content-Type: text/html; charset=utf-8',
36
  'From: ' . get_option( 'bookly_email_sender_name' ) . ' <' . get_option( 'bookly_email_sender' ) . '>',
29
  ) );
30
  }
31
 
32
+ $message = $this->render( '_email_to_support', compact( 'name', 'email', 'msg' ), false );
 
33
  $headers = array(
34
  'Content-Type: text/html; charset=utf-8',
35
  'From: ' . get_option( 'bookly_email_sender_name' ) . ' <' . get_option( 'bookly_email_sender' ) . '>',
lib/NotificationCodes.php CHANGED
@@ -42,7 +42,7 @@ class NotificationCodes
42
  'total_price' => '',
43
  // Extras
44
  'extras' => '',
45
- 'extras_total_price' => '',
46
  // Recurring Appointments
47
  'appointment_schedule' => '',
48
  'appointment_schedule_c' => '',
42
  'total_price' => '',
43
  // Extras
44
  'extras' => '',
45
+ 'extras_total_price' => 0,
46
  // Recurring Appointments
47
  'appointment_schedule' => '',
48
  'appointment_schedule_c' => '',
lib/Updater.php CHANGED
@@ -25,9 +25,6 @@ class Updater extends Base\Updater
25
  add_option( 'bookly_api_server_error_time', '0' );
26
  add_option( 'bookly_grace_notifications', array ( 'bookly' => '0', 'add-ons' => '0', 'sent' => '0' ) );
27
  add_option( 'bookly_grace_hide_admin_notice_time', '0' );
28
- foreach ( apply_filters( 'bookly_plugins', array() ) as $plugin_class ) {
29
- add_option( $plugin_class::getPrefix() . 'grace_start', time() + 2 * WEEK_IN_SECONDS );
30
- }
31
 
32
  $options = array(
33
  'bookly_email_content_type' => 'bookly_email_send_as',
25
  add_option( 'bookly_api_server_error_time', '0' );
26
  add_option( 'bookly_grace_notifications', array ( 'bookly' => '0', 'add-ons' => '0', 'sent' => '0' ) );
27
  add_option( 'bookly_grace_hide_admin_notice_time', '0' );
 
 
 
28
 
29
  $options = array(
30
  'bookly_email_content_type' => 'bookly_email_send_as',
lib/base/Plugin.php CHANGED
@@ -398,13 +398,6 @@ abstract class Plugin
398
  load_plugin_textdomain( $plugin_class::getTextDomain(), false, $plugin_class::getSlug() . '/languages' );
399
  } );
400
 
401
- // Add handlers to Bookly filters.
402
- add_filter( 'bookly_plugins', function ( array $plugins ) use ( $plugin_class ) {
403
- $plugins[ $plugin_class::getSlug() ] = $plugin_class;
404
-
405
- return $plugins;
406
- } );
407
-
408
  // For admin notices about SMS weekly summary and etc.
409
  if ( ! wp_next_scheduled( 'bookly_daily_routine' ) ) {
410
  wp_schedule_event( time(), 'daily', 'bookly_daily_routine' );
398
  load_plugin_textdomain( $plugin_class::getTextDomain(), false, $plugin_class::getSlug() . '/languages' );
399
  } );
400
 
 
 
 
 
 
 
 
401
  // For admin notices about SMS weekly summary and etc.
402
  if ( ! wp_next_scheduled( 'bookly_daily_routine' ) ) {
403
  wp_schedule_event( time(), 'daily', 'bookly_daily_routine' );
lib/entities/Payment.php CHANGED
@@ -29,8 +29,8 @@ class Payment extends Lib\Base\Entity
29
  'id' => array( 'format' => '%d' ),
30
  'created' => array( 'format' => '%s' ),
31
  'type' => array( 'format' => '%s' ),
32
- 'total' => array( 'format' => '%.2f' ),
33
- 'paid' => array( 'format' => '%.2f' ),
34
  'status' => array( 'format' => '%s', 'default' => self::STATUS_COMPLETED ),
35
  'details' => array( 'format' => '%s' ),
36
  );
29
  'id' => array( 'format' => '%d' ),
30
  'created' => array( 'format' => '%s' ),
31
  'type' => array( 'format' => '%s' ),
32
+ 'total' => array( 'format' => '%f' ),
33
+ 'paid' => array( 'format' => '%f' ),
34
  'status' => array( 'format' => '%s', 'default' => self::STATUS_COMPLETED ),
35
  'details' => array( 'format' => '%s' ),
36
  );
lib/entities/Service.php CHANGED
@@ -19,7 +19,7 @@ class Service extends Lib\Base\Entity
19
  'category_id' => array( 'format' => '%d', 'reference' => array( 'entity' => 'Category' ) ),
20
  'title' => array( 'format' => '%s' ),
21
  'duration' => array( 'format' => '%d', 'default' => 900 ),
22
- 'price' => array( 'format' => '%.2f', 'default' => '0' ),
23
  'color' => array( 'format' => '%s' ),
24
  'capacity' => array( 'format' => '%d', 'default' => '1' ),
25
  'padding_left' => array( 'format' => '%d', 'default' => '0' ),
19
  'category_id' => array( 'format' => '%d', 'reference' => array( 'entity' => 'Category' ) ),
20
  'title' => array( 'format' => '%s' ),
21
  'duration' => array( 'format' => '%d', 'default' => 900 ),
22
+ 'price' => array( 'format' => '%f', 'default' => '0' ),
23
  'color' => array( 'format' => '%s' ),
24
  'capacity' => array( 'format' => '%d', 'default' => '1' ),
25
  'padding_left' => array( 'format' => '%d', 'default' => '0' ),
lib/entities/StaffService.php CHANGED
@@ -15,7 +15,7 @@ class StaffService extends Lib\Base\Entity
15
  'id' => array( 'format' => '%d' ),
16
  'staff_id' => array( 'format' => '%d', 'reference' => array( 'entity' => 'Staff' ) ),
17
  'service_id' => array( 'format' => '%d', 'reference' => array( 'entity' => 'Service' ) ),
18
- 'price' => array( 'format' => '%.2f', 'default' => '0' ),
19
  'capacity' => array( 'format' => '%d', 'default' => '1' ),
20
  'deposit' => array( 'format' => '%s', 'default' => '100%' ),
21
  );
15
  'id' => array( 'format' => '%d' ),
16
  'staff_id' => array( 'format' => '%d', 'reference' => array( 'entity' => 'Staff' ) ),
17
  'service_id' => array( 'format' => '%d', 'reference' => array( 'entity' => 'Service' ) ),
18
+ 'price' => array( 'format' => '%f', 'default' => '0' ),
19
  'capacity' => array( 'format' => '%d', 'default' => '1' ),
20
  'deposit' => array( 'format' => '%s', 'default' => '100%' ),
21
  );
lib/utils/DateTime.php CHANGED
@@ -243,6 +243,8 @@ class DateTime
243
  */
244
  public static function secondsToInterval( $duration )
245
  {
 
 
246
  $weeks = (int) ( $duration / WEEK_IN_SECONDS );
247
  $days = (int) ( ( $duration % WEEK_IN_SECONDS ) / DAY_IN_SECONDS );
248
  $hours = (int) ( ( $duration % DAY_IN_SECONDS ) / HOUR_IN_SECONDS );
243
  */
244
  public static function secondsToInterval( $duration )
245
  {
246
+ $duration = (int) $duration;
247
+
248
  $weeks = (int) ( $duration / WEEK_IN_SECONDS );
249
  $days = (int) ( ( $duration % WEEK_IN_SECONDS ) / DAY_IN_SECONDS );
250
  $hours = (int) ( ( $duration % DAY_IN_SECONDS ) / HOUR_IN_SECONDS );
main.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Bookly Lite
4
  Plugin URI: http://booking-wp-plugin.com
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: 13.0
7
  Author: Ladela Interactive
8
  Author URI: http://booking-wp-plugin.com
9
  Text Domain: bookly
3
  Plugin Name: Bookly Lite
4
  Plugin URI: http://booking-wp-plugin.com
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: 13.1
7
  Author: Ladela Interactive
8
  Author URI: http://booking-wp-plugin.com
9
  Text Domain: bookly
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: Ladela
3
  Tags: 2checkout, appointment plugin, authorize.net, booking plugin, calendar, cart, google calendar, paypal, payson, reservation, responsive, stripe, woocommerce, wordpress, wpm
4
  Donate link: http://booking-wp-plugin.com/
5
  Requires at least: 3.7
6
- Tested up to: 4.7.5
7
  Requires PHP: 5.3.7
8
- Stable tag: 13.0
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
 
@@ -205,6 +205,9 @@ Upon the completion of these steps, customers can book appointments. In the Cale
205
 
206
  == Changelog ==
207
 
 
 
 
208
  = 13.0 =
209
  * Added support for <a href="https://codecanyon.net/item/bookly-recurring-appointments-addon/19497634?ref=ladela">Recurring Appointments (Add-on)</a>
210
  * Added new status Rejected for appointments
3
  Tags: 2checkout, appointment plugin, authorize.net, booking plugin, calendar, cart, google calendar, paypal, payson, reservation, responsive, stripe, woocommerce, wordpress, wpm
4
  Donate link: http://booking-wp-plugin.com/
5
  Requires at least: 3.7
6
+ Tested up to: 4.8.2
7
  Requires PHP: 5.3.7
8
+ Stable tag: 13.1
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
 
205
 
206
  == Changelog ==
207
 
208
+ = 13.1 =
209
+ * Added support for WordPress 4.8.2
210
+
211
  = 13.0 =
212
  * Added support for <a href="https://codecanyon.net/item/bookly-recurring-appointments-addon/19497634?ref=ladela">Recurring Appointments (Add-on)</a>
213
  * Added new status Rejected for appointments