Strong Testimonials - Version 3.0.1

Version Description

  • 18.08.2022 -
  • Fixed: strongValidation error on front form ( https://github.com/WPChill/strong-testimonials/issues/326 )
  • Added: Advanced settings tab and logging system
Download this release

Release Info

Developer raldea89
Plugin Icon 128x128 Strong Testimonials
Version 3.0.1
Comparing to
See all releases

Code changes from version 3.0.0 to 3.0.1

admin/class-strong-testimonials-admin-scripts.php CHANGED
@@ -29,6 +29,7 @@ class Strong_Testimonials_Admin_Scripts {
29
  add_action( 'admin_print_styles-wpm-testimonial_page_testimonial-settings', array( __CLASS__, 'admin_settings' ) );
30
  add_action( 'admin_print_styles-wpm-testimonial_page_about-strong-testimonials', array( __CLASS__, 'admin_about' ) );
31
  add_action( 'admin_print_styles-wpm-testimonial_page_testimonial-shortcodes', array( __CLASS__, 'admin_shortcodes' ) );
 
32
 
33
  add_action( 'load-edit.php', array( __CLASS__, 'admin_load_edit' ) );
34
  add_action( 'load-post.php', array( __CLASS__, 'admin_load_post' ) );
@@ -229,6 +230,11 @@ class Strong_Testimonials_Admin_Scripts {
229
  array( 'jquery' ),
230
  $plugin_version,
231
  true );
 
 
 
 
 
232
  }
233
 
234
  /**
@@ -359,6 +365,13 @@ class Strong_Testimonials_Admin_Scripts {
359
  }
360
  }
361
 
 
 
 
 
 
 
 
362
  /**
363
  * Categories
364
  */
29
  add_action( 'admin_print_styles-wpm-testimonial_page_testimonial-settings', array( __CLASS__, 'admin_settings' ) );
30
  add_action( 'admin_print_styles-wpm-testimonial_page_about-strong-testimonials', array( __CLASS__, 'admin_about' ) );
31
  add_action( 'admin_print_styles-wpm-testimonial_page_testimonial-shortcodes', array( __CLASS__, 'admin_shortcodes' ) );
32
+ add_action( 'admin_print_styles-wpm-testimonial_page_strong-testimonials-logs', array( __CLASS__, 'admin_logs_view' ) );
33
 
34
  add_action( 'load-edit.php', array( __CLASS__, 'admin_load_edit' ) );
35
  add_action( 'load-post.php', array( __CLASS__, 'admin_load_post' ) );
230
  array( 'jquery' ),
231
  $plugin_version,
232
  true );
233
+
234
+ wp_register_style( 'wpmtst-logs-style',
235
+ WPMTST_ADMIN_URL . 'css/logs.css',
236
+ array(),
237
+ $plugin_version );
238
  }
239
 
240
  /**
365
  }
366
  }
367
 
368
+ /**
369
+ * Logs View
370
+ */
371
+ public static function admin_logs_view(){
372
+ wp_enqueue_style( 'wpmtst-logs-style' );
373
+ }
374
+
375
  /**
376
  * Categories
377
  */
admin/class-strong-testimonials-upsell.php CHANGED
@@ -120,6 +120,12 @@ class Strong_Testimonials_Upsell {
120
 
121
 
122
  if ( ! defined( 'WPMTST_IMPORTER_VERSION' ) ) {
 
 
 
 
 
 
123
  add_meta_box(
124
  'wpmtst-importer-upsell', // Unique ID
125
  esc_html__( 'Import', 'strong-testimonials' ), // Title
120
 
121
 
122
  if ( ! defined( 'WPMTST_IMPORTER_VERSION' ) ) {
123
+
124
+ // remove "submitdiv" metabox so we can add it back in desired order.
125
+ $post_type = 'wpm-testimonial';
126
+ remove_meta_box( 'post_submit_meta_box', $post_type, 'side' );
127
+ add_meta_box( 'submitdiv', __( 'Publish' ), 'post_submit_meta_box', $post_type, 'side', 'high' );
128
+
129
  add_meta_box(
130
  'wpmtst-importer-upsell', // Unique ID
131
  esc_html__( 'Import', 'strong-testimonials' ), // Title
admin/css/logs.css ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* The logs view screen
2
+ -----------------------------------------------*/
3
+
4
+ .wrap.wpmtst #log-viewer pre {
5
+ font-family: monospace;
6
+ white-space: pre-wrap;
7
+ word-wrap: break-word;
8
+ }
9
+ .wrap.wpmtst #log-viewer {
10
+ background: #fff;
11
+ border: 1px solid #e5e5e5;
12
+ box-shadow: 0 1px 1px rgba(0,0,0,.04);
13
+ padding: 5px 20px;
14
+ margin-top: 6px;
15
+ }
admin/img/logo-long.svg CHANGED
File without changes
admin/settings/class-strong-testimonials-advanced-settings.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Strong_Testimonials_Advanced_Settings{
4
+ const TAB_NAME = 'Advanced Settings';
5
+ const OPTION_NAME = 'strong_testimonials_advanced_settings';
6
+ const GROUP_NAME = 'wpmtst-advanced-settings-group';
7
+
8
+ public static function init()
9
+ {
10
+ add_action( 'wpmtst_register_settings', array( __CLASS__, 'register_settings' ) );
11
+ add_action( 'wpmtst_settings_tabs', array( __CLASS__, 'register_tab' ), 90, 2 );
12
+ add_filter( 'wpmtst_settings_callbacks', array( __CLASS__, 'register_settings_page' ) );
13
+ }
14
+ /**
15
+ * Register settings tab.
16
+ *
17
+ * @param $active_tab
18
+ * @param $url
19
+ */
20
+ public static function register_tab( $active_tab, $url ) {
21
+ printf( '<a href="%s" class="nav-tab %s">%s</a>',
22
+ esc_url( add_query_arg( 'tab', self::TAB_NAME, $url ) ),
23
+ esc_attr( $active_tab == self::TAB_NAME ? 'nav-tab-active' : '' ),
24
+ esc_html__( 'Advanced Settings', 'strong-testimonials' )
25
+ );
26
+ }
27
+
28
+ /**
29
+ * Register settings.
30
+ */
31
+ public static function register_settings() {
32
+ register_setting( self::GROUP_NAME, self::OPTION_NAME );
33
+ }
34
+
35
+ /**
36
+ * Register settings page.
37
+ *
38
+ * @param $pages
39
+ *
40
+ * @return mixed
41
+ */
42
+ public static function register_settings_page( $pages ) {
43
+ $pages[ self::TAB_NAME ] = array( __CLASS__, 'settings_page' );
44
+ return $pages;
45
+ }
46
+
47
+ /**
48
+ * Print settings page.
49
+ */
50
+ public static function settings_page() {
51
+ settings_fields( self::GROUP_NAME );
52
+ include( plugin_dir_path( __FILE__ ) . 'partials/advanced-settings.php' );
53
+ }
54
+ }
55
+ Strong_Testimonials_Advanced_Settings::init();
admin/settings/partials/advanced-settings.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $options = get_option( 'strong_testimonials_advanced_settings' );
4
+
5
+ ?>
6
+ <div class="row">
7
+ <table class="form-table">
8
+ <tbody>
9
+ <tr valign="top">
10
+ <th scope="row" valign="top">
11
+ <?php esc_html_e( 'Debug log', 'strong-testimonials' ); ?>
12
+ </th>
13
+ <td>
14
+ <input id="strong_testimonials_debug_log_enable" name="strong_testimonials_advanced_settings[debug_log]" type="checkbox" <?php echo ( isset($options['debug_log']) && $options['debug_log'] == 'on' ? 'checked' : '') ; ?>/>
15
+ <label class="description strong-testimonials-license-label" for="strong_testimonials_license_key"> <?php esc_html_e( 'Enable debug log. Off by default.', 'strong-testimonials' ); ?> </label>
16
+ <p class="description"><?php esc_html_e( 'Creates debug logs for Strong Testimonial module and it \'s addons.', 'strong-testimonials' ); ?> </p>
17
+ </td>
18
+ </tr>
19
+
20
+ </tbody>
21
+ </table>
22
+ <p class="submit-buttons"><input type="submit" name="submit-form" id="submit-form" class="button button-primary" value="<?php esc_html_e( 'Save changes', 'strong-testimonials' ); ?>"></p>
23
+ </div>
admin/views.php CHANGED
@@ -739,6 +739,9 @@ function wpmtst_form_category_checklist( $view_cats_array ) {
739
  * @since 2.22.0
740
  */
741
  function wpmtst_save_view_sticky() {
 
 
 
742
  $id = filter_input( INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT );
743
  $stickies = get_option( 'wpmtst_sticky_views', array() );
744
  if ( in_array( $id, $stickies ) ) {
739
  * @since 2.22.0
740
  */
741
  function wpmtst_save_view_sticky() {
742
+ if( !current_user_can('edit_posts') ){
743
+ wp_die();
744
+ }
745
  $id = filter_input( INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT );
746
  $stickies = get_option( 'wpmtst_sticky_views', array() );
747
  if ( in_array( $id, $stickies ) ) {
changelog.txt CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
 
2
  = 3.0.0 - 18.07.2022 -
3
  - Added: Optional parameter to function wpmtst_get_success_message
1
+ = 3.0.1 - 18.08.2022 -
2
+ - Fixed: strongValidation error on front form ( https://github.com/WPChill/strong-testimonials/issues/326 )
3
+ - Added: Advanced settings tab and logging system
4
 
5
  = 3.0.0 - 18.07.2022 -
6
  - Added: Optional parameter to function wpmtst_get_success_message
includes/class-strong-testimonials-order.php CHANGED
@@ -257,6 +257,9 @@ class Strong_Testimonials_Order {
257
  * Update menu order in back end.
258
  */
259
  public static function update_menu_order() {
 
 
 
260
  global $wpdb;
261
 
262
  parse_str( $_POST['posts'], $data );
257
  * Update menu order in back end.
258
  */
259
  public static function update_menu_order() {
260
+ if( !current_user_can('edit_posts') ){
261
+ wp_die();
262
+ }
263
  global $wpdb;
264
 
265
  parse_str( $_POST['posts'], $data );
includes/class-strong-view-display.php CHANGED
@@ -46,8 +46,6 @@ class Strong_View_Display extends Strong_View {
46
  */
47
  public function reset_view() {
48
  wp_reset_postdata();
49
- remove_filter( 'wpmtst_build_query', array( $this, 'query_pagination' ) );
50
- remove_filter( 'wpmtst_build_query', array( $this, 'query_infinitescroll' ) );
51
  }
52
 
53
  /**
46
  */
47
  public function reset_view() {
48
  wp_reset_postdata();
 
 
49
  }
50
 
51
  /**
includes/class-strong-view-slideshow.php CHANGED
@@ -41,7 +41,7 @@ class Strong_View_Slideshow extends Strong_View_Display {
41
  // If we can preprocess, we can add the inline style in the <head>.
42
  add_action( 'wp_enqueue_scripts', array( $this, 'add_custom_style' ), 20 );
43
 
44
- wp_reset_postdata();
45
  }
46
 
47
  /**
41
  // If we can preprocess, we can add the inline style in the <head>.
42
  add_action( 'wp_enqueue_scripts', array( $this, 'add_custom_style' ), 20 );
43
 
44
+ do_action( 'wpmtst_view_processed' );
45
  }
46
 
47
  /**
includes/logs/class-strong-testimonials-logger.php ADDED
@@ -0,0 +1,401 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
+
8
+
9
+ /**
10
+ * Strong_File_Logging Class
11
+ *
12
+ * A general use class for logging events and errors.
13
+ *
14
+ * @since 2.51.7
15
+ */
16
+ class Strong_File_Logging {
17
+
18
+ public $is_writable = true;
19
+ private $filename = '';
20
+ private $file = '';
21
+ public $is_logging_enabled = false;
22
+ /**
23
+ * Holds the class object.
24
+ *
25
+ * @since 1.0.0
26
+ *
27
+ * @var object
28
+ */
29
+ public static $instance;
30
+
31
+ /**
32
+ * Returns the singleton instance of the class.
33
+ *
34
+ * @since 2.51.7
35
+ *
36
+ * @return object The Strong_File_Logging object.
37
+ */
38
+ public static function get_instance() {
39
+
40
+ if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Strong_File_Logging ) ) {
41
+ self::$instance = new Strong_File_Logging();
42
+ }
43
+
44
+ return self::$instance;
45
+
46
+ }
47
+
48
+ public function __construct() {
49
+
50
+ $this->is_logging_enabled();
51
+ add_filter( 'wpmtst_submenu_pages', array( $this, 'add_submenu' ) );
52
+ add_action( 'admin_init', array( $this, 'handle_actions' ) );
53
+ }
54
+
55
+ /**
56
+ * Add submenu page.
57
+ *
58
+ * @param $pages
59
+ *
60
+ * @return mixed
61
+ *
62
+ * @since 2.51.7
63
+ */
64
+ public function add_submenu( $pages ) {
65
+ $pages[90] = $this->get_submenu();
66
+ return $pages;
67
+ }
68
+
69
+ /**
70
+ * Return submenu page parameters.
71
+ *
72
+ * @return array
73
+ *
74
+ * @since 2.51.7
75
+ */
76
+ public function get_submenu() {
77
+ return array(
78
+ 'page_title' => esc_html__( 'Logs', 'strong-testimonials' ),
79
+ 'menu_title' => esc_html__( 'Logs', 'strong-testimonials' ),
80
+ 'capability' => 'strong_testimonials_options',
81
+ 'menu_slug' => 'strong-testimonials-logs',
82
+ 'function' => array( $this, 'status_logs_file' ),
83
+ );
84
+ }
85
+
86
+ /**
87
+ * Check if logging is enabled
88
+ *
89
+ * @since 2.51.7
90
+ */
91
+ public function is_logging_enabled() {
92
+ $options = get_option( 'strong_testimonials_advanced_settings' );
93
+ if ( isset( $options['debug_log'] ) && 'on' === $options['debug_log'] ) {
94
+ $this->is_logging_enabled = true;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Return the log file handle.
100
+ *
101
+ * @param string $filename Filename to get the handle for.
102
+ * @return string
103
+ *
104
+ * @since 2.51.7
105
+ */
106
+ public static function get_log_file_handle( $filename ) {
107
+ return substr( $filename, 0, strlen( $filename ) > 48 ? strlen( $filename ) - 48 : strlen( $filename ) - 4 );
108
+ }
109
+
110
+ /**
111
+ * Scan log files
112
+ *
113
+ * @param [type] $path
114
+ * @return void
115
+ *
116
+ * @since 2.51.7
117
+ */
118
+ public static function scan_log_files( $path ) {
119
+ return @scandir( $path ); // @codingStandardsIgnoreLine
120
+ }
121
+
122
+ /**
123
+ * Get all log files in the log directory.
124
+ *
125
+ * @return array
126
+ *
127
+ * @since 2.51.7
128
+ */
129
+ public function get_log_files() {
130
+ $files = self::scan_log_files( WPMTST_LOGS );
131
+ $result = array();
132
+
133
+ if ( ! empty( $files ) ) {
134
+ foreach ( $files as $key => $value ) {
135
+ if ( ! in_array( $value, array( '.', '..' ), true ) ) {
136
+ if ( ! is_dir( $value ) && strstr( $value, '.log' ) ) {
137
+ $result[ sanitize_title( $value ) ] = $value;
138
+ } elseif ( is_dir( WPMTST_LOGS . $value ) ) {
139
+ $subfiles = self::scan_log_files( WPMTST_LOGS . $value );
140
+ if ( ! empty( $subfiles ) ) {
141
+ foreach ( $subfiles as $key => $subvalue ) {
142
+ if ( ! in_array( $subvalue, array( '.', '..' ), true ) ) {
143
+ if ( ! is_dir( $subvalue ) && strstr( $subvalue, '.log' ) ) {
144
+ $result[ sanitize_title( $subvalue ) ] = $value . '/' . $subvalue;
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+
154
+ return $result;
155
+ }
156
+
157
+ /**
158
+ * Handles the delete log and download log actions.
159
+ *
160
+ * @since 2.51.7
161
+ */
162
+ public function handle_actions() {
163
+
164
+ if ( ! empty( $_REQUEST['remove'] ) ) { // phpcs:ignore input var ok, CSRF ok.
165
+ $this->remove_log();
166
+ }
167
+
168
+ if ( ! empty( $_REQUEST['download'] ) ) { // phpcs:ignore input var ok, CSRF ok.
169
+ $this->download_log();
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Show the log page contents for file log handler.
175
+ *
176
+ * @since 2.51.7
177
+ */
178
+ public function status_logs_file() {
179
+ $logs = $this->get_log_files();
180
+
181
+ if ( ! empty( $_REQUEST['log_file'] ) && isset( $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ] ) ) { // phpcs:ignore input var ok, CSRF ok.
182
+ $viewed_log = $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ]; // phpcs:ignore input var ok, CSRF ok.
183
+ } elseif ( ! empty( $logs ) ) {
184
+ $viewed_log = current( $logs );
185
+ }
186
+
187
+ $handle = ! empty( $viewed_log ) ? self::get_log_file_handle( $viewed_log ) : '';
188
+
189
+ include_once __DIR__ . '/html-strong-testimonials-logs-viewer.php';
190
+ }
191
+
192
+ /**
193
+ * Remove/delete the chosen file and it's directory.
194
+ *
195
+ * @since 2.51.7
196
+ */
197
+ public function remove_log() {
198
+ if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( wp_unslash( $_REQUEST['_wpnonce'] ), 'remove_log' ) ) { // phpcs:ignore input var ok, sanitization ok.
199
+ wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'strong-testimonials' ) );
200
+ }
201
+
202
+ if ( ! empty( $_REQUEST['remove'] ) ) { // phpcs:ignore input var ok.
203
+ $this->remove( wp_unslash( $_REQUEST['remove'] ), wp_unslash( $_REQUEST['subdir'] ) ); // phpcs:ignore input var ok, sanitization ok.
204
+ }
205
+
206
+ wp_safe_redirect( esc_url_raw( admin_url( 'edit.php?post_type=wpm-testimonial&page=strong-testimonials-logs' ) ) );
207
+ exit();
208
+ }
209
+
210
+ /**
211
+ * Remove/delete the chosen file and it's directory.
212
+ *
213
+ * @param string $handle Log handle.
214
+ *
215
+ * @return bool
216
+ *
217
+ * @since 2.51.7
218
+ */
219
+ public function remove( $handle, $subdir ) {
220
+ $removed = false;
221
+ $logs = $this->get_log_files();
222
+ $handle = sanitize_title( $handle );
223
+ $subdir = sanitize_title( $subdir );
224
+
225
+ if ( isset( $logs[ $handle ] ) && $logs[ $handle ] ) {
226
+ $file = realpath( trailingslashit( WPMTST_LOGS ) . $logs[ $handle ] );
227
+ if ( 0 === stripos( $file, realpath( trailingslashit( WPMTST_LOGS ) ) ) && is_file( $file ) && is_writable( $file ) ) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable
228
+ $removed = unlink( $file ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink
229
+ if ( $subdir != '' ) {
230
+ rmdir( dirname( $file ) );
231
+ }
232
+ }
233
+ }
234
+ return $removed;
235
+ }
236
+
237
+ /**
238
+ * Download the chosen file.
239
+ *
240
+ * @since 2.51.7
241
+ */
242
+ public function download_log() {
243
+ if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( wp_unslash( $_REQUEST['_wpnonce'] ), 'download_log' ) ) { // phpcs:ignore input var ok, sanitization ok.
244
+ wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'strong-testimonials' ) );
245
+ }
246
+
247
+ if ( ! empty( $_REQUEST['download'] ) ) { // phpcs:ignore input var ok.
248
+ $this->download( wp_unslash( $_REQUEST['download'] ), wp_unslash( $_REQUEST['subdir'] ) ); // phpcs:ignore input var ok, sanitization ok.
249
+ }
250
+
251
+ }
252
+
253
+ /**
254
+ * Download the chosen file.
255
+ *
256
+ * @param string $handle Log handle.
257
+ *
258
+ * @return void
259
+ *
260
+ * @since 2.51.7
261
+ */
262
+ public function download( $handle, $subdir ) {
263
+ $logs = $this->get_log_files();
264
+ $handle = sanitize_title( $handle );
265
+ $subdir = sanitize_title( $subdir );
266
+ if ( isset( $logs[ $handle ] ) && $logs[ $handle ] ) {
267
+ $file = realpath( trailingslashit( WPMTST_LOGS ) . $logs[ $handle ] );
268
+ if ( 0 === stripos( $file, realpath( trailingslashit( WPMTST_LOGS ) ) ) && is_file( $file ) && is_writable( $file ) ) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable
269
+ header( 'Content-Description: File Transfer' );
270
+ header( 'Content-Type: application/octet-stream' );
271
+ header( 'Content-Disposition: attachment; filename="' . basename( $file ) . '"' );
272
+ header( 'Expires: 0' );
273
+ header( 'Cache-Control: must-revalidate' );
274
+ header( 'Pragma: public' );
275
+ header( 'Content-Length: ' . filesize( $file ) );
276
+ ob_clean();
277
+ flush();
278
+ readfile( $file );
279
+ exit();
280
+ }
281
+ }
282
+
283
+ }
284
+
285
+ /**
286
+ * Sets up the log file if it is writable
287
+ *
288
+ * @return void
289
+ *
290
+ * @since 2.51.7
291
+ */
292
+ public function setup_log_file( $importer ) {
293
+ $basedir = trailingslashit( WPMTST_LOGS ) . $importer;
294
+ if ( ! is_dir( $basedir ) ) {
295
+ mkdir( $basedir, 0777, true );
296
+ }
297
+ $this->filename = wp_hash( home_url( '/' ) ) . '-' . $importer . '-st_debug.log';
298
+ $this->file = $basedir . '/' . $this->filename;
299
+ if ( ! is_writeable( WPMTST_LOGS ) ) {
300
+ $this->is_writable = false;
301
+ }
302
+
303
+ }
304
+
305
+ /**
306
+ * Retrieve the log data
307
+ *
308
+ * @return string
309
+ *
310
+ * @since 2.51.7
311
+ */
312
+ public function get_file_contents() {
313
+ return $this->get_file();
314
+ }
315
+
316
+ /**
317
+ * Log message to file
318
+ *
319
+ * @return void
320
+ *
321
+ * @since 2.51.7
322
+ */
323
+ public function log_to_file( $message = '' ) {
324
+ $message = wp_date( 'd-n-Y H:i:s' ) . ' - ' . $message . "\r\n";
325
+ $this->write_to_log( $message );
326
+
327
+ }
328
+
329
+ /**
330
+ * Retrieve the file data is written to
331
+ *
332
+ * @return string
333
+ *
334
+ * @since 2.51.7
335
+ */
336
+ protected function get_file() {
337
+
338
+ $file = '';
339
+
340
+ if ( @file_exists( $this->file ) ) {
341
+
342
+ if ( ! is_writeable( $this->file ) ) {
343
+ $this->is_writable = false;
344
+ }
345
+
346
+ $file = @file_get_contents( $this->file );
347
+ } else {
348
+ @file_put_contents( $this->file, '' );
349
+ @chmod( $this->file, 0664 );
350
+
351
+ }
352
+
353
+ return $file;
354
+ }
355
+
356
+ /**
357
+ * Write the log message
358
+ *
359
+ * @return void
360
+ *
361
+ * @since 2.51.7
362
+ */
363
+ protected function write_to_log( $message = '' ) {
364
+ $file = $this->get_file();
365
+ $file .= $message;
366
+ @file_put_contents( $this->file, $file );
367
+ }
368
+
369
+ /**
370
+ * Return the location of the log file that Strong_File_Logging will use.
371
+ *
372
+ * @return string
373
+ *
374
+ * @since 2.51.7
375
+ */
376
+ public function get_log_file_path() {
377
+ return $this->file;
378
+ }
379
+
380
+ }
381
+
382
+ $GLOBALS['strong_logs'] = Strong_File_Logging::get_instance();
383
+
384
+
385
+ /**
386
+ * Logs a message to the debug log file
387
+ *
388
+ * @param string $message
389
+ * @global $strong_logs Strong_File_Logging Object
390
+ * @return void
391
+ *
392
+ * @since 2.51.7
393
+ */
394
+ function ST_debug_log( $importer = '', $message = '' ) {
395
+ global $strong_logs;
396
+ if ( $strong_logs->is_logging_enabled ) {
397
+ $strong_logs->setup_log_file( $importer );
398
+ $strong_logs->log_to_file( $message );
399
+ }
400
+
401
+ }
includes/logs/html-strong-testimonials-logs-viewer.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit;
4
+ }
5
+ if ( $logs ) : ?>
6
+ <div class="wrap wpmtst">
7
+
8
+ <h1><?php esc_html_e( 'Strong Testimonials Debug Logs', 'strong-testimonials' ); ?></h1>
9
+ <div id="log-viewer-select">
10
+ <div class="alignleft">
11
+ <h2>
12
+ <?php echo esc_html( $viewed_log ); ?>
13
+ <?php
14
+ $subfolder = '';
15
+ if ( strpos( $viewed_log, '/' ) ) {
16
+ $subfolder = explode( '/', $viewed_log )[0];
17
+ $log_name = explode( '/', $viewed_log )[1];
18
+ } else {
19
+ $log_name = $viewed_log;
20
+ }
21
+ ?>
22
+ <?php if ( ! empty( $viewed_log ) ) : ?>
23
+ <a class="page-title-action" href="
24
+ <?php
25
+ echo esc_url(
26
+ wp_nonce_url(
27
+ add_query_arg(
28
+ array(
29
+ 'remove' => sanitize_title( $log_name ),
30
+ 'subdir' => sanitize_title( $subfolder ),
31
+ ),
32
+ admin_url( 'edit.php?post_type=wpm-testimonial&page=strong-testimonials-logs' )
33
+ ),
34
+ 'remove_log'
35
+ )
36
+ );
37
+ ?>
38
+ " class="button"><?php esc_html_e( 'Delete log', 'strong-testimonials' ); ?></a>
39
+ <a class="page-title-action" href="
40
+ <?php
41
+ echo esc_url(
42
+ wp_nonce_url(
43
+ add_query_arg(
44
+ array(
45
+ 'download' => sanitize_title( $log_name ),
46
+ 'subdir' => sanitize_title( $subfolder ),
47
+ ),
48
+ admin_url( 'edit.php?post_type=wpm-testimonial&page=strong-testimonials-logs' )
49
+ ),
50
+ 'download_log'
51
+ )
52
+ );
53
+ ?>
54
+ " class="button"><?php esc_html_e( 'Download log', 'strong-testimonials' ); ?></a>
55
+ <?php endif; ?>
56
+ </h2>
57
+ </div>
58
+ <div class="alignright">
59
+ <form action="<?php echo esc_url( admin_url( 'edit.php?post_type=wpm-testimonial&page=strong-testimonials-logs' ) ); ?>" method="post">
60
+ <select name="log_file">
61
+ <?php foreach ( $logs as $log_key => $log_file ) : ?>
62
+ <?php
63
+ $timestamp = filemtime( WPMTST_LOGS . $log_file );
64
+ $date = sprintf(
65
+ __( '%1$s at %2$s', 'strong-testimonials' ),
66
+ wp_date( 'd-M-y', $timestamp ),
67
+ wp_date( 'h:i:s', $timestamp )
68
+ );
69
+ ?>
70
+ <option value="<?php echo esc_attr( $log_key ); ?>" <?php selected( sanitize_title( $viewed_log ), $log_key ); ?>><?php echo esc_html( $log_file ); ?> (<?php echo esc_html( $date ); ?>)</option>
71
+ <?php endforeach; ?>
72
+ </select>
73
+ <button type="submit" class="button" value="<?php esc_attr_e( 'View', 'strong-testimonials' ); ?>"><?php esc_html_e( 'View', 'strong-testimonials' ); ?></button>
74
+ </form>
75
+ </div>
76
+ <div class="clear"></div>
77
+ </div>
78
+ <div id="log-viewer">
79
+ <pre><?php echo esc_html( file_get_contents( WPMTST_LOGS . $viewed_log ) ); ?></pre>
80
+ </div>
81
+ <?php else : ?>
82
+ <div class="updated inline"><p><?php esc_html_e( 'There are currently no logs to view.', 'strong-testimonials' ); ?></p></div>
83
+ <?php endif; ?>
84
+ </div>
includes/submodules/banner/assets/css/wpchill-welcome.css CHANGED
@@ -1,370 +1,365 @@
1
- #wpcontent {
2
- padding-left: 0 !important;
3
- position: relative;
4
- }
5
-
6
- #wpchill-welcome {
7
- padding-top: 80px;
8
- }
9
-
10
- #wpchill-welcome *, #wpchill-welcome *::before, #wpchill-welcome *::after {
11
- -webkit-box-sizing: border-box;
12
- -moz-box-sizing: border-box;
13
- box-sizing: border-box;
14
- }
15
-
16
- #wpchill-welcome .clear:before {
17
- content: " ";
18
- display: table;
19
- }
20
-
21
- #wpchill-welcome .clear:after {
22
- clear: both;
23
- content: " ";
24
- display: table;
25
- }
26
-
27
- #wpchill-welcome .container {
28
- margin: 0 auto;
29
- max-width: 800px;
30
- padding: 0;
31
- }
32
-
33
- #wpchill-welcome .block {
34
- padding: 40px;
35
- }
36
-
37
- #wpchill-welcome img {
38
- max-width: 100%;
39
- height: auto;
40
- }
41
-
42
- #wpchill-welcome h1 {
43
- color: #222;
44
- font-size: 24px;
45
- margin: 0 0 16px 0;
46
- }
47
-
48
- #wpchill-welcome h5 {
49
- color: #222;
50
- font-size: 16px;
51
- margin: 0 0 8px 0;
52
- }
53
-
54
- #wpchill-welcome h6 {
55
- font-size: 16px;
56
- font-weight: 400;
57
- line-height: 1.6;
58
- margin: 0;
59
- }
60
-
61
- #wpchill-welcome .wpmtst-btn-lg {
62
- font-size: 16px;
63
- font-weight: 600;
64
- padding: 16px 28px;
65
- }
66
-
67
- #wpchill-welcome .wpmtst-btn-block {
68
- display: block;
69
- width: 100%;
70
- }
71
-
72
- #wpchill-welcome .wpmtst-btn {
73
- border: 0;
74
- border-radius: 40px;
75
- cursor: pointer;
76
- display: inline-block;
77
- margin: 0;
78
- text-decoration: none;
79
- text-align: center;
80
- vertical-align: middle;
81
- white-space: nowrap;
82
- box-shadow: none;
83
- }
84
-
85
-
86
- #wpchill-welcome .button-wrap {
87
- max-width: 590px;
88
- margin: 0 auto 0 auto;
89
- }
90
-
91
- #wpchill-welcome .button-wrap .left {
92
- margin-bottom: 10px;
93
- }
94
-
95
- #wpchill-welcome .button-wrap-single a {
96
- font-size: 14px;
97
- }
98
-
99
- #wpchill-welcome .button-wrap-single {
100
- padding: 0 20px;
101
- }
102
-
103
- @media screen and (min-width: 720px) {
104
-
105
- #wpchill-welcome .button-wrap .left {
106
- margin-bottom: 0px;
107
- float: left;
108
- width: 50%;
109
- padding-right: 20px;
110
- }
111
-
112
- #wpchill-welcome .button-wrap .right {
113
- float: right;
114
- width: 50%;
115
- padding-left: 20px;
116
- }
117
-
118
- #wpchill-welcome .button-wrap-single a {
119
- font-size: 16px;
120
- }
121
- }
122
-
123
- /* hero section */
124
- #wpchill-welcome .hero {
125
- background-color: #fff;
126
- border-radius: 10px;
127
- margin-bottom: 30px;
128
- position: relative;
129
- box-shadow: -3px 2px 70px 0px rgba(128, 144, 174, 0.1);
130
- padding-top: 40px;
131
- }
132
-
133
- #wpchill-welcome .hero .mascot {
134
- background-color: #fff;
135
- border-radius: 50%;
136
- height: 90px;
137
- width: 90px;
138
- padding: 28px 28px;
139
- position: absolute;
140
- top: -45px;
141
- left: 50%;
142
- margin-left: -45px;
143
- }
144
-
145
- #wpchill-welcome .hero .video-thumbnail {
146
- display: block;
147
- margin: 0;
148
- width: 100%;
149
- }
150
-
151
- #wpchill-welcome .hero .button-wrap {
152
- margin-top: 20px;
153
- }
154
-
155
-
156
- /* features section */
157
- #wpchill-welcome .features {
158
- background-color: #fff;
159
- border-top-left-radius: 10px;
160
- border-top-right-radius: 10px;
161
- position: relative;
162
- padding-top: 20px;
163
- }
164
-
165
- #wpchill-welcome .features .feature-list {
166
- margin-top: 40px;
167
- }
168
-
169
- #wpchill-welcome .features .feature-block {
170
- margin-bottom: 30px;
171
- }
172
-
173
- @media screen and (min-width: 720px) {
174
-
175
- #wpchill-welcome .block-row-2 .feature-block {
176
- margin: 0 auto;
177
- float: left;
178
- width: 50%;
179
- padding-bottom: 32px;
180
- overflow: auto;
181
- }
182
-
183
- #wpchill-welcome .block-row-3 .feature-block {
184
- margin: 0 auto;
185
- float: left;
186
- width: 33%;
187
- padding-bottom: 32px;
188
- overflow: auto;
189
- }
190
-
191
- #wpchill-welcome .block-row-2 .feature-block:nth-child(odd) {
192
- padding-right: 22px;
193
- clear: both;
194
- }
195
-
196
- #wpchill-welcome .block-row-3 .feature-block:not(:nth-child(3n+3)) {
197
- padding-right: 22px;
198
- }
199
-
200
- #wpchill-welcome .block-row-3 .feature-block:nth-child(3n+1) {
201
- clear: both;
202
- }
203
-
204
- #wpchill-welcome .features .feature-block.last {
205
- padding-left: 22px;
206
- }
207
- .block-row-1 > * {
208
- width: 100%;
209
- }
210
- .block-row{
211
- display:flex;
212
- flex-wrap:wrap;
213
- align-items:flex-start;
214
- flex-direction: row;
215
- justify-content: flex-start;
216
- }
217
-
218
- .block-row-2 > * {
219
- width: 50%;
220
- }
221
-
222
- .block-row-3 > * {
223
- width: 33%;
224
- }
225
-
226
- .block-row-4 > * {
227
- width: 25%;
228
- }
229
- }
230
-
231
- #wpchill-welcome .features .feature-block img {
232
- float: left;
233
- max-width: 44px;
234
- max-height: 44px;
235
- }
236
-
237
- #wpchill-welcome .features .feature-block h5 {
238
- margin-left: 70px;
239
- }
240
-
241
- #wpchill-welcome .features .feature-block p {
242
- margin-left: 70px;
243
- }
244
-
245
- #wpchill-welcome .features .pro-label {
246
- display: inline-block;
247
- line-height: 1;
248
- color: #fff;
249
- padding: 3px 6px;
250
- font-size: 0.75rem;
251
- border-radius: 20px;
252
- vertical-align: text-top;
253
- margin-left: 20px;
254
- }
255
-
256
- #wpchill-welcome .features .feature-list a {
257
- color: #5333ED;
258
- }
259
-
260
- /* upgrade section */
261
- #wpchill-welcome .upgrade {
262
- background-color: white;
263
- text-align: center;
264
- }
265
-
266
- #wpchill-welcome .upgrade h1{
267
- color: #fff;
268
- }
269
-
270
- @media screen and (min-width: 720px) {
271
-
272
- #wpchill-welcome .upgrade .left{
273
- float: left;
274
- width: 50%;
275
- padding-left: 20%;
276
- margin-bottom: 30px;
277
- text-align: left;
278
- }
279
-
280
- #wpchill-welcome .upgrade .right{
281
- float: left;
282
- width: 50%;
283
- padding-right: 20%;
284
- margin-bottom: 30px;
285
- text-align: left;
286
- }
287
- #wpchill-welcome .button-wrap-single{
288
- width: 50%;
289
- margin: 0 auto;
290
- }
291
- }
292
-
293
- /* testimonials section */
294
- #wpchill-welcome .testimonials {
295
- background-color: #fafafa;
296
-
297
- position: relative;
298
- box-shadow: -3px 2px 70px 0px rgba(128, 144, 174, 0.1);
299
- }
300
-
301
- #wpchill-welcome .testimonials .testimonial-block {
302
- padding: 0 16px 32px;
303
- overflow: auto;
304
- margin-top: 40px;
305
- text-align: center;
306
- }
307
-
308
- @media screen and (min-width: 720px) {
309
-
310
- #wpchill-welcome .testimonials .testimonial-block {
311
- float: left;
312
- width: 50%;
313
- }
314
-
315
- }
316
-
317
- #wpchill-welcome .testimonials .testimonial-block p {
318
- font-size: 14px;
319
- font-weight: 400;
320
- line-height: 1.6;
321
- }
322
-
323
- #wpchill-welcome .testimonials .testimonial-block img {
324
- max-width: 60px;
325
- max-height: 60px;
326
- border-radius: 50%;
327
- filter: grayscale(100%);
328
- box-shadow: 0 0 12px rgba(0,0,0,0.15);
329
- }
330
-
331
- /* testimonials footer */
332
- #wpchill-welcome .footer {
333
- background-color: #fff;
334
- border-bottom-left-radius: 10px;
335
- border-bottom-right-radius: 10px;
336
- margin-bottom: 30px;
337
- position: relative;
338
- box-shadow: -3px 2px 70px 0px rgba(128, 144, 174, 0.1);
339
- }
340
-
341
- #wpchill-welcome .container {
342
- position: relative;
343
- width: 100%;
344
- height: 0;
345
- padding-bottom: 56.25%;
346
- }
347
-
348
- #wpchill-welcome .video {
349
- position: absolute;
350
- top: 0;
351
- left: 0;
352
- width: 100%;
353
- height: 100%;
354
- }
355
-
356
- #wpchill-welcome .stars_wrapper svg {
357
- height: 20px;
358
- }
359
-
360
- #wpchill-welcome .wpchill_empty_space{
361
- display:block;
362
- clear:both;
363
- }
364
-
365
- .wpchill_horizontal_delimiter {
366
- background-color: #f0f0f1;
367
- height:20px;
368
- width:100%;
369
- margin:0 auto;
370
  }
1
+ #wpchill-welcome {
2
+ padding-top: 80px;
3
+ }
4
+
5
+ #wpchill-welcome *, #wpchill-welcome *::before, #wpchill-welcome *::after {
6
+ -webkit-box-sizing: border-box;
7
+ -moz-box-sizing: border-box;
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ #wpchill-welcome .clear:before {
12
+ content: " ";
13
+ display: table;
14
+ }
15
+
16
+ #wpchill-welcome .clear:after {
17
+ clear: both;
18
+ content: " ";
19
+ display: table;
20
+ }
21
+
22
+ #wpchill-welcome .container {
23
+ margin: 0 auto;
24
+ max-width: 800px;
25
+ padding: 0;
26
+ }
27
+
28
+ #wpchill-welcome .block {
29
+ padding: 40px;
30
+ }
31
+
32
+ #wpchill-welcome img {
33
+ max-width: 100%;
34
+ height: auto;
35
+ }
36
+
37
+ #wpchill-welcome h1 {
38
+ color: #222;
39
+ font-size: 24px;
40
+ margin: 0 0 16px 0;
41
+ }
42
+
43
+ #wpchill-welcome h5 {
44
+ color: #222;
45
+ font-size: 16px;
46
+ margin: 0 0 8px 0;
47
+ }
48
+
49
+ #wpchill-welcome h6 {
50
+ font-size: 16px;
51
+ font-weight: 400;
52
+ line-height: 1.6;
53
+ margin: 0;
54
+ }
55
+
56
+ #wpchill-welcome .wpmtst-btn-lg {
57
+ font-size: 16px;
58
+ font-weight: 600;
59
+ padding: 16px 28px;
60
+ }
61
+
62
+ #wpchill-welcome .wpmtst-btn-block {
63
+ display: block;
64
+ width: 100%;
65
+ }
66
+
67
+ #wpchill-welcome .wpmtst-btn {
68
+ border: 0;
69
+ border-radius: 40px;
70
+ cursor: pointer;
71
+ display: inline-block;
72
+ margin: 0;
73
+ text-decoration: none;
74
+ text-align: center;
75
+ vertical-align: middle;
76
+ white-space: nowrap;
77
+ box-shadow: none;
78
+ }
79
+
80
+
81
+ #wpchill-welcome .button-wrap {
82
+ max-width: 590px;
83
+ margin: 0 auto 0 auto;
84
+ }
85
+
86
+ #wpchill-welcome .button-wrap .left {
87
+ margin-bottom: 10px;
88
+ }
89
+
90
+ #wpchill-welcome .button-wrap-single a {
91
+ font-size: 14px;
92
+ }
93
+
94
+ #wpchill-welcome .button-wrap-single {
95
+ padding: 0 20px;
96
+ }
97
+
98
+ @media screen and (min-width: 720px) {
99
+
100
+ #wpchill-welcome .button-wrap .left {
101
+ margin-bottom: 0px;
102
+ float: left;
103
+ width: 50%;
104
+ padding-right: 20px;
105
+ }
106
+
107
+ #wpchill-welcome .button-wrap .right {
108
+ float: right;
109
+ width: 50%;
110
+ padding-left: 20px;
111
+ }
112
+
113
+ #wpchill-welcome .button-wrap-single a {
114
+ font-size: 16px;
115
+ }
116
+ }
117
+
118
+ /* hero section */
119
+ #wpchill-welcome .hero {
120
+ background-color: #fff;
121
+ border-radius: 10px;
122
+ margin-bottom: 30px;
123
+ position: relative;
124
+ box-shadow: -3px 2px 70px 0px rgba(128, 144, 174, 0.1);
125
+ padding-top: 40px;
126
+ }
127
+
128
+ #wpchill-welcome .hero .mascot {
129
+ background-color: #fff;
130
+ border-radius: 50%;
131
+ height: 90px;
132
+ width: 90px;
133
+ padding: 28px 28px;
134
+ position: absolute;
135
+ top: -45px;
136
+ left: 50%;
137
+ margin-left: -45px;
138
+ }
139
+
140
+ #wpchill-welcome .hero .video-thumbnail {
141
+ display: block;
142
+ margin: 0;
143
+ width: 100%;
144
+ }
145
+
146
+ #wpchill-welcome .hero .button-wrap {
147
+ margin-top: 20px;
148
+ }
149
+
150
+
151
+ /* features section */
152
+ #wpchill-welcome .features {
153
+ background-color: #fff;
154
+ border-top-left-radius: 10px;
155
+ border-top-right-radius: 10px;
156
+ position: relative;
157
+ padding-top: 20px;
158
+ }
159
+
160
+ #wpchill-welcome .features .feature-list {
161
+ margin-top: 40px;
162
+ }
163
+
164
+ #wpchill-welcome .features .feature-block {
165
+ margin-bottom: 30px;
166
+ }
167
+
168
+ @media screen and (min-width: 720px) {
169
+
170
+ #wpchill-welcome .block-row-2 .feature-block {
171
+ margin: 0 auto;
172
+ float: left;
173
+ width: 50%;
174
+ padding-bottom: 32px;
175
+ overflow: auto;
176
+ }
177
+
178
+ #wpchill-welcome .block-row-3 .feature-block {
179
+ margin: 0 auto;
180
+ float: left;
181
+ width: 33%;
182
+ padding-bottom: 32px;
183
+ overflow: auto;
184
+ }
185
+
186
+ #wpchill-welcome .block-row-2 .feature-block:nth-child(odd) {
187
+ padding-right: 22px;
188
+ clear: both;
189
+ }
190
+
191
+ #wpchill-welcome .block-row-3 .feature-block:not(:nth-child(3n+3)) {
192
+ padding-right: 22px;
193
+ }
194
+
195
+ #wpchill-welcome .block-row-3 .feature-block:nth-child(3n+1) {
196
+ clear: both;
197
+ }
198
+
199
+ #wpchill-welcome .features .feature-block.last {
200
+ padding-left: 22px;
201
+ }
202
+ .block-row-1 > * {
203
+ width: 100%;
204
+ }
205
+ .block-row{
206
+ display:flex;
207
+ flex-wrap:wrap;
208
+ align-items:flex-start;
209
+ flex-direction: row;
210
+ justify-content: flex-start;
211
+ }
212
+
213
+ .block-row-2 > * {
214
+ width: 50%;
215
+ }
216
+
217
+ .block-row-3 > * {
218
+ width: 33%;
219
+ }
220
+
221
+ .block-row-4 > * {
222
+ width: 25%;
223
+ }
224
+ }
225
+
226
+ #wpchill-welcome .features .feature-block img {
227
+ float: left;
228
+ max-width: 44px;
229
+ max-height: 44px;
230
+ }
231
+
232
+ #wpchill-welcome .features .feature-block h5 {
233
+ margin-left: 70px;
234
+ }
235
+
236
+ #wpchill-welcome .features .feature-block p {
237
+ margin-left: 70px;
238
+ }
239
+
240
+ #wpchill-welcome .features .pro-label {
241
+ display: inline-block;
242
+ line-height: 1;
243
+ color: #fff;
244
+ padding: 3px 6px;
245
+ font-size: 0.75rem;
246
+ border-radius: 20px;
247
+ vertical-align: text-top;
248
+ margin-left: 20px;
249
+ }
250
+
251
+ #wpchill-welcome .features .feature-list a {
252
+ color: #5333ED;
253
+ }
254
+
255
+ /* upgrade section */
256
+ #wpchill-welcome .upgrade {
257
+ background-color: white;
258
+ text-align: center;
259
+ }
260
+
261
+ #wpchill-welcome .upgrade h1{
262
+ color: #fff;
263
+ }
264
+
265
+ @media screen and (min-width: 720px) {
266
+
267
+ #wpchill-welcome .upgrade .left{
268
+ float: left;
269
+ width: 50%;
270
+ padding-left: 20%;
271
+ margin-bottom: 30px;
272
+ text-align: left;
273
+ }
274
+
275
+ #wpchill-welcome .upgrade .right{
276
+ float: left;
277
+ width: 50%;
278
+ padding-right: 20%;
279
+ margin-bottom: 30px;
280
+ text-align: left;
281
+ }
282
+ #wpchill-welcome .button-wrap-single{
283
+ width: 50%;
284
+ margin: 0 auto;
285
+ }
286
+ }
287
+
288
+ /* testimonials section */
289
+ #wpchill-welcome .testimonials {
290
+ background-color: #fafafa;
291
+
292
+ position: relative;
293
+ box-shadow: -3px 2px 70px 0px rgba(128, 144, 174, 0.1);
294
+ }
295
+
296
+ #wpchill-welcome .testimonials .testimonial-block {
297
+ padding: 0 16px 32px;
298
+ overflow: auto;
299
+ margin-top: 40px;
300
+ text-align: center;
301
+ }
302
+
303
+ @media screen and (min-width: 720px) {
304
+
305
+ #wpchill-welcome .testimonials .testimonial-block {
306
+ float: left;
307
+ width: 50%;
308
+ }
309
+
310
+ }
311
+
312
+ #wpchill-welcome .testimonials .testimonial-block p {
313
+ font-size: 14px;
314
+ font-weight: 400;
315
+ line-height: 1.6;
316
+ }
317
+
318
+ #wpchill-welcome .testimonials .testimonial-block img {
319
+ max-width: 60px;
320
+ max-height: 60px;
321
+ border-radius: 50%;
322
+ filter: grayscale(100%);
323
+ box-shadow: 0 0 12px rgba(0,0,0,0.15);
324
+ }
325
+
326
+ /* testimonials footer */
327
+ #wpchill-welcome .footer {
328
+ background-color: #fff;
329
+ border-bottom-left-radius: 10px;
330
+ border-bottom-right-radius: 10px;
331
+ margin-bottom: 30px;
332
+ position: relative;
333
+ box-shadow: -3px 2px 70px 0px rgba(128, 144, 174, 0.1);
334
+ }
335
+
336
+ #wpchill-welcome .container {
337
+ position: relative;
338
+ width: 100%;
339
+ height: 0;
340
+ padding-bottom: 56.25%;
341
+ }
342
+
343
+ #wpchill-welcome .video {
344
+ position: absolute;
345
+ top: 0;
346
+ left: 0;
347
+ width: 100%;
348
+ height: 100%;
349
+ }
350
+
351
+ #wpchill-welcome .stars_wrapper svg {
352
+ height: 20px;
353
+ }
354
+
355
+ #wpchill-welcome .wpchill_empty_space{
356
+ display:block;
357
+ clear:both;
358
+ }
359
+
360
+ .wpchill_horizontal_delimiter {
361
+ background-color: #f0f0f1;
362
+ height:20px;
363
+ width:100%;
364
+ margin:0 auto;
 
 
 
 
 
365
  }
includes/submodules/banner/assets/img/star.svg CHANGED
@@ -1,12 +1,12 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
- <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="-274 399.8 53 43.1" style="enable-background:new -274 399.8 53 43.1;" xml:space="preserve">
5
- <style type="text/css">
6
- .st0{fill:#5333ED;}
7
- </style>
8
- <g>
9
- <path class="st0" d="M-234.8,415h-11.5l-3.6-11c-1.4-4.3-3.7-4.3-5.1,0l-3.6,11h-11.5c-4.5,0-5.3,2.2-1.6,4.8l9.3,6.8l-3.6,11
10
- c-1.4,4.3,0.4,5.7,4.1,3l9.3-6.8l9.3,6.8c3.7,2.7,5.5,1.3,4.1-3l-3.6-11l9.3-6.8C-229.6,417.1-230.3,415-234.8,415z"/>
11
- </g>
12
- </svg>
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="-274 399.8 53 43.1" style="enable-background:new -274 399.8 53 43.1;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{fill:#5333ED;}
7
+ </style>
8
+ <g>
9
+ <path class="st0" d="M-234.8,415h-11.5l-3.6-11c-1.4-4.3-3.7-4.3-5.1,0l-3.6,11h-11.5c-4.5,0-5.3,2.2-1.6,4.8l9.3,6.8l-3.6,11
10
+ c-1.4,4.3,0.4,5.7,4.1,3l9.3-6.8l9.3,6.8c3.7,2.7,5.5,1.3,4.1-3l-3.6-11l9.3-6.8C-229.6,417.1-230.3,415-234.8,415z"/>
11
+ </g>
12
+ </svg>
includes/submodules/banner/class-wpchill-welcome.php CHANGED
@@ -1,260 +1,260 @@
1
- <?php
2
-
3
- if ( ! class_exists( 'WPChill_Welcome' ) ) {
4
-
5
- class WPChill_Welcome {
6
-
7
- /**
8
- * Contains the instance of the Class
9
- *
10
- * @since 1.0.0
11
- * @param WPChill_Welcome $instance
12
- */
13
- private static $instance = null;
14
-
15
- /**
16
- * @since 1.0.0
17
- * @param string $textdomain - wpchill textdomain
18
- */
19
- public $textdomain = 'wpchill';
20
-
21
- private function __construct() {
22
- add_action( 'admin_footer', array( $this, 'welcome_style' ) );
23
- }
24
-
25
- /**
26
- * @since 1.0.0
27
- * Singleton
28
- */
29
- public static function get_instance() {
30
-
31
- if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WPChill_Welcome ) ) {
32
- self::$instance = new WPChill_Welcome();
33
- }
34
-
35
- return self::$instance;
36
- }
37
-
38
- /**
39
- * @since 1.0.0
40
- * Enqueue admin Wellcome style
41
- */
42
- public function welcome_style() {
43
- wp_register_style( 'wpchill-welcome-style', plugins_url( '/assets/css/wpchill-welcome.css', __FILE__ ), null, '1.0.0' );
44
- wp_print_styles( array( 'wpchill-welcome-style' ) );
45
- }
46
-
47
- /**
48
- * @since 1.0.0
49
- * Renders buttons
50
- *
51
- * @param string $text
52
- *
53
- * @param string $url
54
- *
55
- * @param bool $fill
56
- *
57
- * @param string $color
58
- */
59
- public function display_button( $text, $link, $fill = true, $color = '#5D3CE4' ) {
60
- $style = 'style="background-color:' . sanitize_hex_color( $color ) . ';border-color:' . sanitize_hex_color( $color ) . ';color:#fff;"';
61
- echo '<a href="' . esc_attr( $link ) . '" ' . ( $fill ? $style : '' ) . ' class="wpmtst-btn wpmtst-btn-block wpmtst-btn-lg">' . esc_html( $text ) . '</a>';
62
- }
63
-
64
- /**
65
- * @since 1.0.0
66
- * Renders extension html
67
- *
68
- * @param string $title
69
- *
70
- * @param string $description
71
- *
72
- * @param string $icon (icon URL)
73
- *
74
- * @param bool $pro
75
- */
76
- public function display_extension( $title, $description = '', $icon = '', $pro = false, $pro_color = '#5333ED' ) {
77
-
78
- echo '<div class="feature-block">';
79
- if ( '' != $icon ) {
80
- echo '<img src="' . esc_attr( $icon ) . '">';
81
- }
82
- echo '<h5>' . esc_html( $title ) . ( ( $pro ) ? '<div style="background-color:' . esc_attr( $pro_color ) . '" class="pro-label">PRO</div>' : '' ) . '</h5>';
83
- echo '<p>' . esc_html( $description ) . '</p>';
84
- echo '</div>';
85
- }
86
-
87
- /**
88
- * @since 1.0.0
89
- * Displays h1 heading
90
- *
91
- * @param string $text
92
- *
93
- * @param string $position
94
- */
95
- public function display_heading( $text, $position = 'center' ) {
96
- echo '<h1 style="text-align: ' . esc_attr( $position ) . ';" >' . esc_html( $text ) . '</h1>';
97
- }
98
-
99
- /**
100
- * @since 1.0.0
101
- * Displays h6 subheading
102
- *
103
- * @param string $text
104
- *
105
- * @param string $position
106
- */
107
- public function display_subheading( $text, $position = 'center' ) {
108
- echo '<h6 style="text-align: ' . esc_attr( $position ) . '" >' . esc_html( $text ) . '</h6>';
109
- }
110
-
111
-
112
- /**
113
- * @since 1.0.0
114
- * Renders testimonial block
115
- *
116
- * @param string $text
117
- *
118
- * @param string $icon
119
- *
120
- * @param string $name
121
- *
122
- * @param string $job (reviewer's job or company)
123
- */
124
- public function display_testimonial( $text, $icon = '', $name = '', $job = '', $star_color = '' ) {
125
-
126
- echo '<div class="testimonial-block">';
127
- if ( '' != $icon ) {
128
- echo '<img src=" ' . esc_url( $icon ) . ' "/>';
129
- }
130
- echo '<p>' . esc_html( $text ) . '</p>';
131
-
132
- $this->display_stars( $star_color );
133
-
134
- if ( '' !== $name || '' !== $job ) {
135
- echo '<p>';
136
-
137
- if ( '' !== $name ) {
138
- echo '<strong>' . esc_html( $name ) . '</strong><br/>';
139
- }
140
- if ( '' !== $job ) {
141
- echo esc_html( $job );
142
- }
143
- echo '</p>';
144
- }
145
-
146
- echo '</div>';
147
- }
148
-
149
- /**
150
- * @since 1.0.0
151
- * Renders a UL list
152
- *
153
- * @param array $items - array of list items
154
- */
155
- public function display_listing( $items ) {
156
- echo '<ul>';
157
-
158
- foreach ( $items as $item ) {
159
- echo '<li>' . esc_html( $item ) . '</li>';
160
- }
161
-
162
- echo '</ul>';
163
- }
164
-
165
-
166
- /**
167
- * @since 1.0.0
168
- * Renders a UL list
169
- *
170
- * @param string $url - youtube.com url
171
- */
172
- public function display_video( $url ) {
173
- parse_str( wp_parse_url( esc_url( $url ), PHP_URL_QUERY ), $video_vars );
174
- echo '<div class="container"><iframe src="https://www.youtube.com/embed/' . esc_attr( $video_vars['v'] ) . '" frameborder="0" allowfullscreen class="video"></iframe></div>';
175
- }
176
-
177
- /**
178
- * @since 1.0.0
179
- * Renders rating stars block
180
- *
181
- * @param string $color - code of the star color fill
182
- */
183
- public function display_stars( $color ) {
184
- $color = ( '' === $color ) ? '#FFD700' : sanitize_hex_color( $color );
185
- $id = wp_rand( 0, 9999999 );
186
- $star = '<svg version="1.1" class="svg-' . absint( $id ) . '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-274 399.8 53 43.1" style="enable-background:new -274 399.8 53 43.1;" xml:space="preserve">
187
- <g>
188
- <path class="st0" d="M-234.8,415h-11.5l-3.6-11c-1.4-4.3-3.7-4.3-5.1,0l-3.6,11h-11.5c-4.5,0-5.3,2.2-1.6,4.8l9.3,6.8l-3.6,11
189
- c-1.4,4.3,0.4,5.7,4.1,3l9.3-6.8l9.3,6.8c3.7,2.7,5.5,1.3,4.1-3l-3.6-11l9.3-6.8C-229.6,417.1-230.3,415-234.8,415z"/>
190
- </g>
191
- </svg>';
192
-
193
- $svg_args = array(
194
- 'svg' => array(
195
- 'class' => true,
196
- 'aria-hidden' => true,
197
- 'aria-labelledby' => true,
198
- 'role' => true,
199
- 'xmlns' => true,
200
- 'width' => true,
201
- 'height' => true,
202
- 'viewbox' => true, // <= Must be lower case!
203
- 'id' => true,
204
- ),
205
- 'g' => array( 'fill' => true ),
206
- 'title' => array( 'title' => true ),
207
- 'path' => array(
208
- 'd' => true,
209
- 'fill' => true,
210
- ),
211
- 'style' => array( 'type' => true ),
212
- );
213
-
214
- echo '<style>';
215
- echo '.svg-' . absint( $id ) . '{ fill:' . sanitize_hex_color( $color ) . ';}';
216
- echo '</style>';
217
- echo '<div class="stars_wrapper">' . wp_kses( $star . $star . $star . $star . $star, $svg_args ) . '</div>';
218
- }
219
-
220
- /**
221
- * @since 1.0.0
222
- * Columns wrapper start
223
- *
224
- * @param int $cols - # of columns the contained objects should be displayed as. (1/2/3)
225
- */
226
- public function layout_start( $cols = 2, $class = '' ) {
227
- echo '<div class="' . esc_attr( $class ) . ' block-row block-row-' . absint( $cols ) . '">';
228
- }
229
-
230
- /**
231
- * @since 1.0.0
232
- * Columns wrapper end
233
- */
234
- public function layout_end() {
235
- echo '</div>';
236
- }
237
-
238
- /**
239
- * @since 1.0.0
240
- * Renders empty space block
241
- *
242
- * @param int $height - height(px) of space
243
- */
244
- public function display_empty_space( $height = 25 ) {
245
-
246
- echo '<div class="wpchill_empty_space" style="height:' . esc_attr( $height ) . 'px;"></div>';
247
- }
248
-
249
- /**
250
- * Horizontal delimiter
251
- *
252
- * @return void
253
- * @since 1.0.0
254
- */
255
- public function horizontal_delimiter() {
256
- echo '<hr class="wpchill_horizontal_delimiter">';
257
- }
258
-
259
- }
260
- }
1
+ <?php
2
+
3
+ if ( ! class_exists( 'WPChill_Welcome' ) ) {
4
+
5
+ class WPChill_Welcome {
6
+
7
+ /**
8
+ * Contains the instance of the Class
9
+ *
10
+ * @since 1.0.0
11
+ * @param WPChill_Welcome $instance
12
+ */
13
+ private static $instance = null;
14
+
15
+ /**
16
+ * @since 1.0.0
17
+ * @param string $textdomain - wpchill textdomain
18
+ */
19
+ public $textdomain = 'wpchill';
20
+
21
+ private function __construct() {
22
+ add_action( 'admin_footer', array( $this, 'welcome_style' ) );
23
+ }
24
+
25
+ /**
26
+ * @since 1.0.0
27
+ * Singleton
28
+ */
29
+ public static function get_instance() {
30
+
31
+ if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WPChill_Welcome ) ) {
32
+ self::$instance = new WPChill_Welcome();
33
+ }
34
+
35
+ return self::$instance;
36
+ }
37
+
38
+ /**
39
+ * @since 1.0.0
40
+ * Enqueue admin Wellcome style
41
+ */
42
+ public function welcome_style() {
43
+ wp_register_style( 'wpchill-welcome-style', plugins_url( '/assets/css/wpchill-welcome.css', __FILE__ ), null, '1.0.0' );
44
+ wp_print_styles( array( 'wpchill-welcome-style' ) );
45
+ }
46
+
47
+ /**
48
+ * @since 1.0.0
49
+ * Renders buttons
50
+ *
51
+ * @param string $text
52
+ *
53
+ * @param string $url
54
+ *
55
+ * @param bool $fill
56
+ *
57
+ * @param string $color
58
+ */
59
+ public function display_button( $text, $link, $fill = true, $color = '#5D3CE4' ) {
60
+ $style = 'style="background-color:' . sanitize_hex_color( $color ) . ';border-color:' . sanitize_hex_color( $color ) . ';color:#fff;"';
61
+ echo '<a href="' . esc_attr( $link ) . '" ' . ( $fill ? $style : '' ) . ' class="wpmtst-btn wpmtst-btn-block wpmtst-btn-lg">' . esc_html( $text ) . '</a>';
62
+ }
63
+
64
+ /**
65
+ * @since 1.0.0
66
+ * Renders extension html
67
+ *
68
+ * @param string $title
69
+ *
70
+ * @param string $description
71
+ *
72
+ * @param string $icon (icon URL)
73
+ *
74
+ * @param bool $pro
75
+ */
76
+ public function display_extension( $title, $description = '', $icon = '', $pro = false, $pro_color = '#5333ED' ) {
77
+
78
+ echo '<div class="feature-block">';
79
+ if ( '' != $icon ) {
80
+ echo '<img src="' . esc_attr( $icon ) . '">';
81
+ }
82
+ echo '<h5>' . esc_html( $title ) . ( ( $pro ) ? '<div style="background-color:' . esc_attr( $pro_color ) . '" class="pro-label">PRO</div>' : '' ) . '</h5>';
83
+ echo '<p>' . esc_html( $description ) . '</p>';
84
+ echo '</div>';
85
+ }
86
+
87
+ /**
88
+ * @since 1.0.0
89
+ * Displays h1 heading
90
+ *
91
+ * @param string $text
92
+ *
93
+ * @param string $position
94
+ */
95
+ public function display_heading( $text, $position = 'center' ) {
96
+ echo '<h1 style="text-align: ' . esc_attr( $position ) . ';" >' . esc_html( $text ) . '</h1>';
97
+ }
98
+
99
+ /**
100
+ * @since 1.0.0
101
+ * Displays h6 subheading
102
+ *
103
+ * @param string $text
104
+ *
105
+ * @param string $position
106
+ */
107
+ public function display_subheading( $text, $position = 'center' ) {
108
+ echo '<h6 style="text-align: ' . esc_attr( $position ) . '" >' . esc_html( $text ) . '</h6>';
109
+ }
110
+
111
+
112
+ /**
113
+ * @since 1.0.0
114
+ * Renders testimonial block
115
+ *
116
+ * @param string $text
117
+ *
118
+ * @param string $icon
119
+ *
120
+ * @param string $name
121
+ *
122
+ * @param string $job (reviewer's job or company)
123
+ */
124
+ public function display_testimonial( $text, $icon = '', $name = '', $job = '', $star_color = '' ) {
125
+
126
+ echo '<div class="testimonial-block">';
127
+ if ( '' != $icon ) {
128
+ echo '<img src=" ' . esc_url( $icon ) . ' "/>';
129
+ }
130
+ echo '<p>' . esc_html( $text ) . '</p>';
131
+
132
+ $this->display_stars( $star_color );
133
+
134
+ if ( '' !== $name || '' !== $job ) {
135
+ echo '<p>';
136
+
137
+ if ( '' !== $name ) {
138
+ echo '<strong>' . esc_html( $name ) . '</strong><br/>';
139
+ }
140
+ if ( '' !== $job ) {
141
+ echo esc_html( $job );
142
+ }
143
+ echo '</p>';
144
+ }
145
+
146
+ echo '</div>';
147
+ }
148
+
149
+ /**
150
+ * @since 1.0.0
151
+ * Renders a UL list
152
+ *
153
+ * @param array $items - array of list items
154
+ */
155
+ public function display_listing( $items ) {
156
+ echo '<ul>';
157
+
158
+ foreach ( $items as $item ) {
159
+ echo '<li>' . esc_html( $item ) . '</li>';
160
+ }
161
+
162
+ echo '</ul>';
163
+ }
164
+
165
+
166
+ /**
167
+ * @since 1.0.0
168
+ * Renders a UL list
169
+ *
170
+ * @param string $url - youtube.com url
171
+ */
172
+ public function display_video( $url ) {
173
+ parse_str( wp_parse_url( esc_url( $url ), PHP_URL_QUERY ), $video_vars );
174
+ echo '<div class="container"><iframe src="https://www.youtube.com/embed/' . esc_attr( $video_vars['v'] ) . '" frameborder="0" allowfullscreen class="video"></iframe></div>';
175
+ }
176
+
177
+ /**
178
+ * @since 1.0.0
179
+ * Renders rating stars block
180
+ *
181
+ * @param string $color - code of the star color fill
182
+ */
183
+ public function display_stars( $color ) {
184
+ $color = ( '' === $color ) ? '#FFD700' : sanitize_hex_color( $color );
185
+ $id = wp_rand( 0, 9999999 );
186
+ $star = '<svg version="1.1" class="svg-' . absint( $id ) . '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-274 399.8 53 43.1" style="enable-background:new -274 399.8 53 43.1;" xml:space="preserve">
187
+ <g>
188
+ <path class="st0" d="M-234.8,415h-11.5l-3.6-11c-1.4-4.3-3.7-4.3-5.1,0l-3.6,11h-11.5c-4.5,0-5.3,2.2-1.6,4.8l9.3,6.8l-3.6,11
189
+ c-1.4,4.3,0.4,5.7,4.1,3l9.3-6.8l9.3,6.8c3.7,2.7,5.5,1.3,4.1-3l-3.6-11l9.3-6.8C-229.6,417.1-230.3,415-234.8,415z"/>
190
+ </g>
191
+ </svg>';
192
+
193
+ $svg_args = array(
194
+ 'svg' => array(
195
+ 'class' => true,
196
+ 'aria-hidden' => true,
197
+ 'aria-labelledby' => true,
198
+ 'role' => true,
199
+ 'xmlns' => true,
200
+ 'width' => true,
201
+ 'height' => true,
202
+ 'viewbox' => true, // <= Must be lower case!
203
+ 'id' => true,
204
+ ),
205
+ 'g' => array( 'fill' => true ),
206
+ 'title' => array( 'title' => true ),
207
+ 'path' => array(
208
+ 'd' => true,
209
+ 'fill' => true,
210
+ ),
211
+ 'style' => array( 'type' => true ),
212
+ );
213
+
214
+ echo '<style>';
215
+ echo '.svg-' . absint( $id ) . '{ fill:' . sanitize_hex_color( $color ) . ';}';
216
+ echo '</style>';
217
+ echo '<div class="stars_wrapper">' . wp_kses( $star . $star . $star . $star . $star, $svg_args ) . '</div>';
218
+ }
219
+
220
+ /**
221
+ * @since 1.0.0
222
+ * Columns wrapper start
223
+ *
224
+ * @param int $cols - # of columns the contained objects should be displayed as. (1/2/3)
225
+ */
226
+ public function layout_start( $cols = 2, $class = '' ) {
227
+ echo '<div class="' . esc_attr( $class ) . ' block-row block-row-' . absint( $cols ) . '">';
228
+ }
229
+
230
+ /**
231
+ * @since 1.0.0
232
+ * Columns wrapper end
233
+ */
234
+ public function layout_end() {
235
+ echo '</div>';
236
+ }
237
+
238
+ /**
239
+ * @since 1.0.0
240
+ * Renders empty space block
241
+ *
242
+ * @param int $height - height(px) of space
243
+ */
244
+ public function display_empty_space( $height = 25 ) {
245
+
246
+ echo '<div class="wpchill_empty_space" style="height:' . esc_attr( $height ) . 'px;"></div>';
247
+ }
248
+
249
+ /**
250
+ * Horizontal delimiter
251
+ *
252
+ * @return void
253
+ * @since 1.0.0
254
+ */
255
+ public function horizontal_delimiter() {
256
+ echo '<hr class="wpchill_horizontal_delimiter">';
257
+ }
258
+
259
+ }
260
+ }
includes/submodules/banner/readme.txt CHANGED
@@ -1 +1 @@
1
- Readme
1
+ Readme
public/js/controller.min.js CHANGED
@@ -1,383 +1 @@
1
- /**
2
- * Component Controller
3
- *
4
- * Version 1.2
5
- * For Strong Testimonials version 2.31
6
- *
7
- * @namespace window.strongControllerParms
8
- */
9
-
10
- 'use strict';
11
- var debugit = false;
12
-
13
- var strongController = {
14
-
15
- grids: {},
16
-
17
- iframes: {},
18
-
19
- defaults: {
20
- initializeOn: 'windowLoad',
21
- method: '',
22
- universalTimer: 500,
23
- observerTimer: 500,
24
- containerId: 'page', // = what we listen to (try page > content > primary)
25
- addedNodeId: 'content', // = what we listen for
26
- event: '',
27
- script: '',
28
- debug: false
29
- },
30
-
31
- config: {},
32
-
33
- setup: function (settings) {
34
- // Convert strings to integers
35
- settings.universalTimer = parseInt(settings.universalTimer);
36
- settings.observerTimer = parseInt(settings.observerTimer);
37
- // Convert strings to booleans
38
- settings.debug = !!settings.debug;
39
- debugit = settings.debug;
40
- this.config = jQuery.extend({}, this.defaults, settings);
41
- },
42
-
43
- mutationObserver: window.MutationObserver || window.WebKitMutationObserver,
44
-
45
- eventListenerSupported: window.addEventListener,
46
-
47
- checkInit: function () {
48
- return jQuery('.strong-view[data-state="idle"]').length;
49
- },
50
-
51
- /**
52
- * Initialize sliders.
53
- */
54
- initSliders: function () {
55
- var sliders = jQuery('.strong-view.slider-container[data-state="idle"]');
56
- if (debugit) console.log('sliders found:', sliders.length);
57
- if (sliders.length) {
58
- // Initialize independently
59
- sliders.each(function () {
60
-
61
- var $slider = jQuery(this);
62
-
63
- // don't init if it's only a single testimonial
64
- var count = $slider.data('count');
65
- if( count !== undefined && count === 1 ) {
66
- return;
67
- }
68
-
69
- $slider.strongSlider();
70
- });
71
- }
72
- },
73
-
74
- /**
75
- * Initialize paginated views.
76
- */
77
- initPagers: function () {
78
- var pagers = jQuery('.strong-pager[data-state="idle"]');
79
- if (debugit) console.log('pagers found:', pagers.length);
80
- if (pagers.length) {
81
- pagers.each(function () {
82
- jQuery(this).strongPager();
83
- });
84
- }
85
- },
86
-
87
- /**
88
- * Initialize layouts.
89
- */
90
- initLayouts: function () {
91
- /*
92
- * Masonry
93
- */
94
- this.grids = jQuery('.strong-view[data-state="idle"] .strong-masonry');
95
- if (debugit) console.log('Masonry found:', this.grids.length);
96
- if (this.grids.length) {
97
- // Add our element sizing.
98
- this.grids.prepend('<div class="grid-sizer"></div><div class="gutter-sizer"></div>');
99
-
100
- // Initialize Masonry after images are loaded.
101
- this.grids.imagesLoaded(function () {
102
- strongController.grids.masonry({
103
- columnWidth: '.grid-sizer',
104
- gutter: '.gutter-sizer',
105
- itemSelector: '.wpmtst-testimonial',
106
- percentPosition: true
107
- });
108
-
109
- strongController.grids.closest('.strong-view').attr('data-state', 'init');
110
- });
111
- }
112
-
113
- },
114
-
115
- /**
116
- * Initialize form validation.
117
- */
118
- initForm: function () {
119
- var forms = jQuery('.strong-form[data-state="idle"]');
120
- var messages = jQuery('.wpmtst-testimonial-success');
121
- if (debugit) console.log('forms found:', forms.length);
122
- if (debugit) console.log('messages found:', messages.length);
123
- if (forms.length || messages.length) {
124
- jQuery( forms ).each(function() {
125
- var eachform = new strongValidation(this);
126
- });
127
- // initialize Captcha plugins here
128
- }
129
- },
130
-
131
- /**
132
- * Look for iframes.
133
- */
134
- initIframes: function () {
135
- this.iframes = jQuery('iframe');
136
- },
137
-
138
- /**
139
- * Listen for custom events from other scripts.
140
- */
141
- customEvents: function () {
142
- addEventListener( 'toggleFullContent', function (event) {
143
- if (strongController.grids.length) {
144
- strongController.grids.masonry();
145
- }
146
- });
147
- },
148
-
149
- /**
150
- * Create observer that reacts to nodes added or removed.
151
- *
152
- * https://stackoverflow.com/a/14570614/51600
153
- */
154
- observer: function (obj, callback) {
155
- if (this.mutationObserver) {
156
-
157
- // Define a new observer
158
- var obs = new this.mutationObserver(function (mutations) {
159
- // Loop through mutations
160
- for (var i = 0; i < mutations.length; i++) {
161
- if (mutations[i].addedNodes.length) {
162
- if (debugit) console.log('mutation observed', mutations);
163
- // Loop through added nodes
164
- for (var j = 0; j < mutations[i].addedNodes.length; j++) {
165
- if (mutations[i].addedNodes[j].id === strongController.config.containerId) {
166
- if (debugit) console.log('+', strongController.config.containerId);
167
- callback();
168
- return;
169
- }
170
- }
171
- }
172
- }
173
- });
174
- // Have the observer observe obj for changes
175
- obs.observe(obj, {childList: true, subtree: true});
176
-
177
- } else if (this.eventListenerSupported) {
178
-
179
- obj.addEventListener('DOMNodeInserted', function (e) {
180
- /** currentTarget **/
181
- if (e.currentTarget.id === obj.id) {
182
- if (debugit) console.log('DOMNodeInserted:', e.currentTarget.id);
183
- callback();
184
- }
185
- }, false);
186
-
187
- }
188
- },
189
-
190
- /**
191
- * Timer variables
192
- */
193
- intervalId: null,
194
- timeoutId: null,
195
-
196
- /**
197
- * Set up interval
198
- */
199
- newInterval: function () {
200
- strongController.intervalId = setInterval(function tick () {
201
- if (debugit) console.log('tick > checkInit', strongController.checkInit());
202
-
203
- // Check for uninitialized components (sliders, paginated, layouts)
204
- if (strongController.checkInit()) {
205
- strongController.start();
206
- }
207
- }, strongController.config.universalTimer);
208
- },
209
-
210
- /**
211
- * Set up timeout
212
- */
213
- newTimeout: function () {
214
- strongController.timeoutId = setTimeout(function tick () {
215
- if (debugit) console.log('tick > checkInit', strongController.checkInit());
216
-
217
- // Check for uninitialized components (sliders, paginated, layouts)
218
- if (strongController.checkInit()) {
219
- strongController.start();
220
- }
221
- }, strongController.config.observerTimer);
222
- },
223
-
224
- /**
225
- * Initialize controller.
226
- */
227
- init: function () {
228
- if (debugit) console.log('strongController init');
229
-
230
- // Get settings
231
- var settings = {};
232
- if (typeof window.strongControllerParms !== 'undefined') {
233
- settings = window.strongControllerParms;
234
- } else {
235
- if (debugit) console.log('settings not found');
236
- }
237
-
238
- // Configure
239
- this.setup(settings);
240
- if (debugit) console.log('config', this.config);
241
-
242
- /*
243
- * Start on specific event
244
- */
245
- if ('documentReady' === this.config.initializeOn) {
246
-
247
- jQuery(document).ready(function () {
248
- if (debugit) console.log('document ready');
249
- // Start components.
250
- strongController.start();
251
- // Listen.
252
- strongController.listen();
253
- });
254
-
255
- } else { // Fail-safe
256
-
257
- jQuery(window).on('load', function () {
258
- if (debugit) console.log('window load');
259
- // Start components.
260
- strongController.start();
261
- // Listen.
262
- strongController.listen();
263
- });
264
-
265
- }
266
-
267
- // Regardless of initializeOn setting, check for embeds in Masonry on window load.
268
- jQuery(window).on('load', function () {
269
- strongController.listenForIframeReady();
270
- });
271
-
272
- jQuery('textarea.max-length, input.text.max-length').on('keyup', function() {
273
- var maxLength = jQuery(this).attr('maxlength');
274
- var textLength = jQuery(this).val().length;
275
- if (maxLength !== null) {
276
- jQuery(this).parent().find('.max-length-counter').html(textLength + ' characters out of ' + maxLength);
277
- }
278
- });
279
-
280
- },
281
-
282
- /**
283
- * Start components.
284
- */
285
- start: function () {
286
- if (debugit) console.log('start');
287
- strongController.initSliders();
288
- strongController.initPagers();
289
- strongController.initLayouts();
290
- strongController.initForm();
291
- strongController.initIframes();
292
- strongController.customEvents();
293
- },
294
-
295
- /**
296
- * Listen.
297
- */
298
- listen: function () {
299
- if (debugit) console.log('listen');
300
-
301
- switch (this.config.method) {
302
- case 'universal':
303
- // Set a timer to check for idle components.
304
- this.newInterval();
305
- break;
306
-
307
- case 'observer':
308
- // Observe a specific DOM element on a timer.
309
- // Calling start() here is too soon; the transition is not complete yet.
310
- this.observer(document.getElementById(this.config.containerId), this.newTimeout);
311
- break;
312
-
313
- case 'event':
314
- // The theme/plugin uses an event emitter.
315
-
316
- // jQuery Pjax -!- Not working in any theme tested yet -!-
317
- // event name = pjax:end
318
-
319
- // Pjax by MoOx
320
- // @link https://github.com/MoOx/pjax
321
- // event name = pjax:success
322
-
323
- // Ajax Pagination and Infinite Scroll by Malinky
324
- // @link https://wordpress.org/plugins/malinky-ajax-pagination/
325
- // event name = malinkyLoadPostsComplete
326
-
327
- document.addEventListener(this.config.event, this.start);
328
- break;
329
-
330
- case 'script':
331
- // The theme/plugin uses a dispatcher.
332
-
333
- switch (this.config.script) {
334
- case 'barba':
335
- // Barba
336
- // @link http://barbajs.org/
337
- if (typeof Barba === 'object' && Barba.hasOwnProperty('Dispatcher')) {
338
- Barba.Dispatcher.on('transitionCompleted', this.start);
339
- }
340
- break;
341
- default:
342
- }
343
- break;
344
-
345
- default:
346
- // no Pjax support
347
- }
348
- },
349
-
350
- /**
351
- * Listen.
352
- */
353
- listenForIframeReady: function () {
354
- if (debugit) console.log('listenForIframeReady');
355
-
356
- if (strongController.iframes.length && strongController.grids.length) {
357
-
358
- strongController.iframes.ready(function () {
359
- // still needs a moment to render
360
- setTimeout(function () {
361
- strongController.grids.masonry();
362
- if (debugit) console.log('listenForIframeReady', 'timeout 1');
363
- }, 1000);
364
- // just in case
365
- setTimeout(function () {
366
- strongController.grids.masonry();
367
- if (debugit) console.log('listenForIframeReady', 'timeout 2');
368
- }, 2000);
369
- });
370
-
371
- } else {
372
-
373
- if (debugit) console.log('listenForIframeReady', 'no iframes or Masonry found');
374
-
375
- }
376
- }
377
- };
378
-
379
- // Initialize controller.
380
- strongController.init();
381
-
382
-
383
-
1
+ "use strict";var debugit=!1,strongController={grids:{},iframes:{},defaults:{initializeOn:"windowLoad",method:"",universalTimer:500,observerTimer:500,containerId:"page",addedNodeId:"content",event:"",script:"",debug:!1},config:{},setup:function(t){t.universalTimer=parseInt(t.universalTimer),t.observerTimer=parseInt(t.observerTimer),t.debug=!!t.debug,debugit=t.debug,this.config=jQuery.extend({},this.defaults,t)},mutationObserver:window.MutationObserver||window.WebKitMutationObserver,eventListenerSupported:window.addEventListener,checkInit:function(){return jQuery('.strong-view[data-state="idle"]').length},initSliders:function(){var t=jQuery('.strong-view.slider-container[data-state="idle"]');debugit&&console.log("sliders found:",t.length),t.length&&t.each(function(){var t=jQuery(this),e=t.data("count");void 0!==e&&1===e||t.strongSlider()})},initPagers:function(){var t=jQuery('.strong-pager[data-state="idle"]');debugit&&console.log("pagers found:",t.length),t.length&&t.each(function(){jQuery(this).strongPager()})},initLayouts:function(){this.grids=jQuery('.strong-view[data-state="idle"] .strong-masonry'),debugit&&console.log("Masonry found:",this.grids.length),this.grids.length&&(this.grids.prepend('<div class="grid-sizer"></div><div class="gutter-sizer"></div>'),this.grids.imagesLoaded(function(){strongController.grids.masonry({columnWidth:".grid-sizer",gutter:".gutter-sizer",itemSelector:".wpmtst-testimonial",percentPosition:!0}),strongController.grids.closest(".strong-view").attr("data-state","init")}))},initForm:function(){var t=jQuery('.strong-form[data-state="idle"]'),e=jQuery(".wpmtst-testimonial-success");debugit&&console.log("forms found:",t.length),debugit&&console.log("messages found:",e.length),(t.length||e.length)&&jQuery(t).each(function(){new strongValidation(this)})},initIframes:function(){this.iframes=jQuery("iframe")},customEvents:function(){addEventListener("toggleFullContent",function(t){strongController.grids.length&&strongController.grids.masonry()})},observer:function(t,e){this.mutationObserver?new this.mutationObserver(function(t){for(var n=0;n<t.length;n++)if(t[n].addedNodes.length){debugit&&console.log("mutation observed",t);for(var o=0;o<t[n].addedNodes.length;o++)if(t[n].addedNodes[o].id===strongController.config.containerId)return debugit&&console.log("+",strongController.config.containerId),void e()}}).observe(t,{childList:!0,subtree:!0}):this.eventListenerSupported&&t.addEventListener("DOMNodeInserted",function(n){n.currentTarget.id===t.id&&(debugit&&console.log("DOMNodeInserted:",n.currentTarget.id),e())},!1)},intervalId:null,timeoutId:null,newInterval:function(){strongController.intervalId=setInterval(function(){debugit&&console.log("tick > checkInit",strongController.checkInit()),strongController.checkInit()&&strongController.start()},strongController.config.universalTimer)},newTimeout:function(){strongController.timeoutId=setTimeout(function(){debugit&&console.log("tick > checkInit",strongController.checkInit()),strongController.checkInit()&&strongController.start()},strongController.config.observerTimer)},init:function(){debugit&&console.log("strongController init");var t={};void 0!==window.strongControllerParms?t=window.strongControllerParms:debugit&&console.log("settings not found"),this.setup(t),debugit&&console.log("config",this.config),"documentReady"===this.config.initializeOn?jQuery(document).ready(function(){debugit&&console.log("document ready"),strongController.start(),strongController.listen()}):jQuery(window).on("load",function(){debugit&&console.log("window load"),strongController.start(),strongController.listen()}),jQuery(window).on("load",function(){strongController.listenForIframeReady()}),jQuery("textarea.max-length, input.text.max-length").on("keyup",function(){var t=jQuery(this).attr("maxlength"),e=jQuery(this).val().length;null!==t&&jQuery(this).parent().find(".max-length-counter").html(e+" characters out of "+t)})},start:function(){debugit&&console.log("start"),strongController.initSliders(),strongController.initPagers(),strongController.initLayouts(),strongController.initForm(),strongController.initIframes(),strongController.customEvents()},listen:function(){switch(debugit&&console.log("listen"),this.config.method){case"universal":this.newInterval();break;case"observer":this.observer(document.getElementById(this.config.containerId),this.newTimeout);break;case"event":document.addEventListener(this.config.event,this.start);break;case"script":switch(this.config.script){case"barba":"object"==typeof Barba&&Barba.hasOwnProperty("Dispatcher")&&Barba.Dispatcher.on("transitionCompleted",this.start)}}},listenForIframeReady:function(){debugit&&console.log("listenForIframeReady"),strongController.iframes.length&&strongController.grids.length?strongController.iframes.ready(function(){setTimeout(function(){strongController.grids.masonry(),debugit&&console.log("listenForIframeReady","timeout 1")},1e3),setTimeout(function(){strongController.grids.masonry(),debugit&&console.log("listenForIframeReady","timeout 2")},2e3)}):debugit&&console.log("listenForIframeReady","no iframes or Masonry found")}};strongController.init();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/js/lib/form-validation/form-validation.js CHANGED
@@ -2,276 +2,279 @@
2
  * Submission form validation
3
  */
4
 
5
- function strongValidation(form) {
6
-
7
- this.form = jQuery(form).find('form');
8
- this.formID = this.form.data('formid');
9
-
10
- this.defaults = {
11
- ajaxUrl: '',
12
- display: {
13
- successMessage: false
14
- },
15
- scroll: {
16
- onError: true,
17
- onErrorOffset: 100,
18
- onSuccess: true,
19
- onSuccessOffset: 100
20
- },
21
- fields: {},
22
- };
23
-
24
- this.settings = {};
25
- this.rules = {};
26
-
27
- this.init();
28
- }
29
-
30
- strongValidation.prototype.setOpts = function (options) {
31
- this.settings = jQuery.extend({}, this.defaults, options);
32
- };
33
-
34
  /**
35
  * Add custom validation rule to star-rating pseudo elements.
36
  */
37
- strongValidation.prototype.setRules = function () {
38
- for (var i = 0; i < this.settings.fields.length; i++) {
39
 
40
- if ('rating' === this.settings.fields[i].type) {
41
- if (1 === this.settings.fields[i].required) {
42
- this.rules[this.settings.fields[i].name] = {ratingRequired: true};
43
- }
44
- }
45
-
46
- }
47
- };
48
 
 
 
49
  /**
50
  * Initialize.
51
  */
52
- strongValidation.prototype.init = function () {
53
-
54
- var strongForm = {};
55
 
56
- if (typeof window['strongForm'] !== 'undefined') {
57
- strongForm = this.form.data("config");
58
- }
59
 
60
- this.setOpts(strongForm);
61
-
62
- if (this.settings.display.successMessage) {
63
-
64
- this.scrollOnSuccess();
65
 
66
- } else {
67
 
68
- this.setRules();
69
- this.changeEvents();
70
- this.customValidators();
71
- this.validateForm();
72
 
73
- }
74
 
75
- };
76
 
77
- strongValidation.prototype.changeEvents = function () {
 
 
 
78
 
79
- // Trim blanks
80
- jQuery('input[type="text"], input[type="url"], input[type="email"], textarea', '.wpmtst-submission-form').on('change blur', function (e) {
81
- e.target.value = e.target.value.trim();
82
- });
83
 
84
- // Add protocol if missing
85
- // Thanks http://stackoverflow.com/a/36429927/51600
86
- jQuery('input[type=url]').on('change', function () {
87
- if (this.value.length && !/^https*:\/\//.test(this.value)) {
88
- this.value = 'https://' + this.value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  }
90
- });
91
-
92
- // Star ratings
93
- var ratings = document.getElementsByClassName('strong-rating');
94
- for (var i = 0; i < ratings.length; i++) {
95
- // Handle keystrokes
96
- ratings[i].addEventListener('click', this.handleRadioEvent, true);
97
- ratings[i].addEventListener('keyup', this.handleRadioEvent, true);
98
- // Validate on change
99
- ratings[i].addEventListener('change', function () { jQuery(this).valid(); }, true);
100
- }
101
-
102
- };
103
-
104
- /**
105
- * Show overlay during form submission.
106
- */
107
- strongValidation.prototype.disableForm = function () {
108
- //apply form wait buffer only for the submited form
109
- jQuery('.strong-form-wait[data-formid="'+this.formID+'"]').show();
110
- this.form.find( '.wpmtst_submit_testimonial' ).prop( 'disabled', true );
111
- };
112
-
113
- /**
114
- * Hide overlay after form submission.
115
- */
116
- strongValidation.prototype.enableForm = function () {
117
- jQuery('.strong-form-wait[data-formid="'+this.formID+'"]').hide();
118
- this.form.find( '.wpmtst_submit_testimonial' ).prop( 'disabled', false );
119
- };
120
-
121
- strongValidation.prototype.handleRadioEvent = function (e) {
122
- // If key 0-5 fired the event, trigger click on that star (including hidden zero).
123
- if (e.keyCode >= 48 && e.keyCode <= 53) {
124
- var key = e.keyCode - 48;
125
- jQuery(this).find('input[type="radio"][value=' + key + ']').trigger('click');
126
- }
127
- };
128
-
129
- strongValidation.prototype.customValidators = function () {
130
- /**
131
- * Only use elements that can legitimately have a 'name' attribute:
132
- * <button>, <form>, <fieldset>, <iframe>, <input>, <keygen>, <object>,
133
- * <output>, <select>, <textarea>, <map>, <meta>, <param>
134
- *
135
- * @link https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
136
- *
137
- * jQuery Validate v1.16.0
138
- * As of 6/10/2017
139
- */
140
- jQuery.validator.addMethod('ratingRequired', function (value, element) {
141
- return jQuery(element).find('input:checked').val() > 0;
142
- }, jQuery.validator.messages.required);
143
- };
144
- strongValidation.prototype.validateForm = function () {
145
-
146
- //remember current object for function calls later
147
- var instance = this;
148
- /**
149
- * Validate the form
150
- */
151
- this.form.validate({
152
-
153
- onfocusout: false,
154
-
155
- focusInvalid: false,
156
-
157
- invalidHandler: function (form, validator) {
158
-
159
- // Focus first invalid input
160
- var errors = validator.numberOfInvalids();
161
- if (errors) {
162
- if (instance.settings.scroll.onError) {
163
- if (typeof validator.errorList[0] !== 'undefined') {
164
- var firstError = jQuery(validator.errorList[0].element);
165
- var fieldOffset = firstError.closest('.form-field').offset();
166
- var scrollTop = fieldOffset.top - instance.settings.scroll.onErrorOffset;
167
- jQuery('html, body').animate({scrollTop: scrollTop}, 800, function () { firstError.focus(); });
168
- }
169
- } else {
170
- validator.errorList[0].element.focus();
171
- }
172
- }
173
- },
174
-
175
- submitHandler: function () {
176
- instance.disableForm();
177
- // If Ajax
178
- if (instance.settings.ajaxUrl !== '') {
179
-
180
- window.onbeforeunload = function() {
181
- return "Please wait while the form is submitted.";
182
- }
183
-
184
- var formOptions = {
185
- url: instance.settings.ajaxUrl,
186
- data: {
187
- action: 'wpmtst_form2'
188
- },
189
- success: function(success){ instance.showResponse(success); },
190
- };
191
- instance.form.ajaxSubmit(formOptions);
192
-
193
- } else {
194
-
195
- instance.form.get(0).submit();
196
- }
197
- },
198
-
199
- /* Normalizer not working */
200
- // normalizer: function( value ) {
201
- // return jQuery.trim( value )
202
- // },
203
-
204
- rules: this.rules,
205
-
206
- errorPlacement: function (error, element) {
207
- error.appendTo(element.closest('div.form-field'));
208
- },
209
-
210
- highlight: function (element, errorClass, validClass) {
211
- if (element.type === 'checkbox') {
212
- jQuery(element).closest('.field-wrap').addClass(errorClass).removeClass(validClass);
213
- } else if ('rating' === jQuery(element).data('fieldType')) {
214
- jQuery(element).closest('.field-wrap').addClass(errorClass).removeClass(validClass);
215
- } else {
216
- jQuery(element).addClass(errorClass).removeClass(validClass);
217
- }
218
- },
219
-
220
- unhighlight: function (element, errorClass, validClass) {
221
- if (element.type === 'checkbox') {
222
- jQuery(element).closest('.field-wrap').removeClass(errorClass).addClass(validClass);
223
- } else if ('rating' === jQuery(element).data('fieldType')) {
224
- jQuery(element).closest('.field-wrap').removeClass(errorClass).addClass(validClass);
225
- } else {
226
- jQuery(element).removeClass(errorClass).addClass(validClass);
227
- }
228
- }
229
-
230
- });
231
-
232
-
233
- };
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  /**
236
  * Display message/errors upon Ajax submission
237
  *
238
  * @param response
239
  */
240
- strongValidation.prototype.showResponse = function (response) {
241
- window.onbeforeunload = null;
242
- this.enableForm();
243
- var obj = JSON.parse(response);
244
- if (obj.success) {
245
- this.form.parent().html(obj.message);
246
- this.scrollOnSuccess();
247
- } else {
248
- for (var key in obj.errors) {
249
- if (obj.errors.hasOwnProperty(key)) {
250
- this.form.children('.field-' + key)
251
- .find('span.error')
252
- .remove()
253
- .end()
254
- .append('<span class="error">' + obj.errors[key] + '</span>');
255
- }
 
256
  }
257
- }
258
- };
259
-
260
  /**
261
  * Scroll to success message
262
  */
263
- strongValidation.prototype.scrollOnSuccess = function () {
264
- if (this.settings.scroll.onSuccess) {
265
- var containerOffset, scrollTop;
266
- containerOffset = jQuery('.wpmtst-form-id-'+this.formID).find('.wpmtst-testimonial-success').offset();
267
- if (containerOffset) {
268
- scrollTop = containerOffset.top - this.settings.scroll.onSuccessOffset;
269
- // is WordPress admin bar showing?
270
- if (jQuery('#wpadminbar').length) {
271
- scrollTop -= 32;
272
- }
273
- jQuery('html, body').animate({scrollTop: scrollTop}, 800);
 
274
  }
275
- }
276
- };
277
-
2
  * Submission form validation
3
  */
4
 
5
+ class strongValidation {
6
+
7
+ constructor(form) {
8
+ this.form = jQuery(form).find('form');
9
+ this.formID = this.form.data('formid');
10
+
11
+ this.defaults = {
12
+ ajaxUrl: '',
13
+ display: {
14
+ successMessage: false
15
+ },
16
+ scroll : {
17
+ onError : true,
18
+ onErrorOffset : 100,
19
+ onSuccess : true,
20
+ onSuccessOffset: 100
21
+ },
22
+ fields : {},
23
+ };
24
+
25
+ this.settings = {};
26
+ this.rules = {};
27
+
28
+ this.init();
29
+ }
30
+
31
+ setOpts(options) {
32
+ this.settings = jQuery.extend({}, this.defaults, options);
33
+ }
34
  /**
35
  * Add custom validation rule to star-rating pseudo elements.
36
  */
37
+ setRules() {
38
+ for (var i = 0; i < this.settings.fields.length; i++) {
39
 
40
+ if ('rating' === this.settings.fields[i].type) {
41
+ if (1 === this.settings.fields[i].required) {
42
+ this.rules[this.settings.fields[i].name] = {ratingRequired: true};
43
+ }
44
+ }
 
 
 
45
 
46
+ }
47
+ }
48
  /**
49
  * Initialize.
50
  */
51
+ init() {
 
 
52
 
53
+ var strongForm = {};
 
 
54
 
55
+ if (typeof window['strongForm'] !== 'undefined') {
56
+ strongForm = this.form.data("config");
57
+ }
 
 
58
 
59
+ this.setOpts(strongForm);
60
 
61
+ if (this.settings.display.successMessage) {
 
 
 
62
 
63
+ this.scrollOnSuccess();
64
 
65
+ } else {
66
 
67
+ this.setRules();
68
+ this.changeEvents();
69
+ this.customValidators();
70
+ this.validateForm();
71
 
72
+ }
 
 
 
73
 
74
+ }
75
+
76
+ changeEvents() {
77
+
78
+ // Trim blanks
79
+ jQuery('input[type="text"], input[type="url"], input[type="email"], textarea', '.wpmtst-submission-form').on('change blur', function (e) {
80
+ e.target.value = e.target.value.trim();
81
+ });
82
+
83
+ // Add protocol if missing
84
+ // Thanks http://stackoverflow.com/a/36429927/51600
85
+ jQuery('input[type=url]').on('change', function () {
86
+ if (this.value.length && !/^https*:\/\//.test(this.value)) {
87
+ this.value = 'https://' + this.value;
88
+ }
89
+ });
90
+
91
+ // Star ratings
92
+ var ratings = document.getElementsByClassName('strong-rating');
93
+ for (var i = 0; i < ratings.length; i++) {
94
+ // Handle keystrokes
95
+ ratings[i].addEventListener('click', this.handleRadioEvent, true);
96
+ ratings[i].addEventListener('keyup', this.handleRadioEvent, true);
97
+ // Validate on change
98
+ ratings[i].addEventListener('change', function () {
99
+ jQuery(this).valid();
100
+ }, true);
101
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
+ }
104
+ /**
105
+ * Show overlay during form submission.
106
+ */
107
+ disableForm() {
108
+ //apply form wait buffer only for the submited form
109
+ jQuery('.strong-form-wait[data-formid="' + this.formID + '"]').show();
110
+ this.form.find('.wpmtst_submit_testimonial').prop('disabled', true);
111
+ }
112
+ /**
113
+ * Hide overlay after form submission.
114
+ */
115
+ enableForm() {
116
+ jQuery('.strong-form-wait[data-formid="' + this.formID + '"]').hide();
117
+ this.form.find('.wpmtst_submit_testimonial').prop('disabled', false);
118
+ }
119
+
120
+ handleRadioEvent(e) {
121
+ // If key 0-5 fired the event, trigger click on that star (including hidden zero).
122
+ if (e.keyCode >= 48 && e.keyCode <= 53) {
123
+ var key = e.keyCode - 48;
124
+ jQuery(this).find('input[type="radio"][value=' + key + ']').trigger('click');
125
+ }
126
+ }
127
+
128
+ customValidators() {
129
+ /**
130
+ * Only use elements that can legitimately have a 'name' attribute:
131
+ * <button>, <form>, <fieldset>, <iframe>, <input>, <keygen>, <object>,
132
+ * <output>, <select>, <textarea>, <map>, <meta>, <param>
133
+ *
134
+ * @link https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
135
+ *
136
+ * jQuery Validate v1.16.0
137
+ * As of 6/10/2017
138
+ */
139
+ jQuery.validator.addMethod('ratingRequired', function (value, element) {
140
+ return jQuery(element).find('input:checked').val() > 0;
141
+ }, jQuery.validator.messages.required);
142
+ }
143
+
144
+ validateForm() {
145
+
146
+ //remember current object for function calls later
147
+ var instance = this;
148
+ /**
149
+ * Validate the form
150
+ */
151
+ this.form.validate(
152
+ {
153
+
154
+ onfocusout: false,
155
+
156
+ focusInvalid: false,
157
+
158
+ invalidHandler: function (form, validator) {
159
+
160
+ // Focus first invalid input
161
+ var errors = validator.numberOfInvalids();
162
+ if (errors) {
163
+ if (instance.settings.scroll.onError) {
164
+ if (typeof validator.errorList[0] !== 'undefined') {
165
+ var firstError = jQuery(validator.errorList[0].element);
166
+ var fieldOffset = firstError.closest('.form-field').offset();
167
+ var scrollTop = fieldOffset.top - instance.settings.scroll.onErrorOffset;
168
+ jQuery('html, body').animate({scrollTop: scrollTop}, 800, function () {
169
+ firstError.focus();
170
+ });
171
+ }
172
+ } else {
173
+ validator.errorList[0].element.focus();
174
+ }
175
+ }
176
+ },
177
+
178
+ submitHandler: function () {
179
+ instance.disableForm();
180
+ // If Ajax
181
+ if (instance.settings.ajaxUrl !== '') {
182
+
183
+ window.onbeforeunload = function () {
184
+ return "Please wait while the form is submitted.";
185
+ }
186
+
187
+ var formOptions = {
188
+ url : instance.settings.ajaxUrl,
189
+ data : {
190
+ action: 'wpmtst_form2'
191
+ },
192
+ success: function (success) {
193
+ instance.showResponse(success);
194
+ },
195
+ };
196
+ instance.form.ajaxSubmit(formOptions);
197
+
198
+ } else {
199
+
200
+ instance.form.get(0).submit();
201
+ }
202
+ },
203
+
204
+ /* Normalizer not working */
205
+ // normalizer: function( value ) {
206
+ // return jQuery.trim( value )
207
+ // },
208
+
209
+ rules: this.rules,
210
+
211
+ errorPlacement: function (error, element) {
212
+ error.appendTo(element.closest('div.form-field'));
213
+ },
214
+
215
+ highlight: function (element, errorClass, validClass) {
216
+ if (element.type === 'checkbox') {
217
+ jQuery(element).closest('.field-wrap').addClass(errorClass).removeClass(validClass);
218
+ } else if ('rating' === jQuery(element).data('fieldType')) {
219
+ jQuery(element).closest('.field-wrap').addClass(errorClass).removeClass(validClass);
220
+ } else {
221
+ jQuery(element).addClass(errorClass).removeClass(validClass);
222
+ }
223
+ },
224
+
225
+ unhighlight: function (element, errorClass, validClass) {
226
+ if (element.type === 'checkbox') {
227
+ jQuery(element).closest('.field-wrap').removeClass(errorClass).addClass(validClass);
228
+ } else if ('rating' === jQuery(element).data('fieldType')) {
229
+ jQuery(element).closest('.field-wrap').removeClass(errorClass).addClass(validClass);
230
+ } else {
231
+ jQuery(element).removeClass(errorClass).addClass(validClass);
232
+ }
233
+ }
234
+
235
+ });
236
+
237
+
238
+ }
239
  /**
240
  * Display message/errors upon Ajax submission
241
  *
242
  * @param response
243
  */
244
+ showResponse(response) {
245
+ window.onbeforeunload = null;
246
+ this.enableForm();
247
+ var obj = JSON.parse(response);
248
+ if (obj.success) {
249
+ this.form.parent().html(obj.message);
250
+ this.scrollOnSuccess();
251
+ } else {
252
+ for (var key in obj.errors) {
253
+ if (obj.errors.hasOwnProperty(key)) {
254
+ this.form.children('.field-' + key)
255
+ .find('span.error')
256
+ .remove()
257
+ .end()
258
+ .append('<span class="error">' + obj.errors[key] + '</span>');
259
+ }
260
+ }
261
  }
262
+ }
 
 
263
  /**
264
  * Scroll to success message
265
  */
266
+ scrollOnSuccess() {
267
+ if (this.settings.scroll.onSuccess) {
268
+ var containerOffset, scrollTop;
269
+ containerOffset = jQuery('.wpmtst-form-id-' + this.formID).find('.wpmtst-testimonial-success').offset();
270
+ if (containerOffset) {
271
+ scrollTop = containerOffset.top - this.settings.scroll.onSuccessOffset;
272
+ // is WordPress admin bar showing?
273
+ if (jQuery('#wpadminbar').length) {
274
+ scrollTop -= 32;
275
+ }
276
+ jQuery('html, body').animate({scrollTop: scrollTop}, 800);
277
+ }
278
  }
279
+ }
280
+ }
 
public/js/lib/form-validation/form-validation.min.js CHANGED
@@ -1 +1 @@
1
- var strongValidation={defaults:{ajaxUrl:"",display:{successMessage:!1},scroll:{onError:!0,onErrorOffset:100,onSuccess:!0,onSuccessOffset:100},fields:{}},settings:{},setOpts:function(a){this.settings=jQuery.extend({},this.defaults,a)},rules:{},setRules:function(){for(var a=0;a<this.settings.fields.length;a++)"rating"===this.settings.fields[a].type&&1===this.settings.fields[a].required&&(this.rules[this.settings.fields[a].name]={ratingRequired:!0})},init:function(){var a={};"undefined"!=typeof window.strongForm&&(a=window.strongForm),this.setOpts(a),this.settings.display.successMessage?this.scrollOnSuccess():(this.setRules(),this.changeEvents(),this.customValidators(),this.validateForm())},changeEvents:function(){jQuery('input[type="text"], input[type="url"], input[type="email"], textarea',"#wpmtst-submission-form").on("change blur",function(a){a.target.value=a.target.value.trim()}),jQuery("input[type=url]").on("change",function(){this.value.length&&!/^https*:\/\//.test(this.value)&&(this.value="https://"+this.value)});for(var a=document.getElementsByClassName("strong-rating"),b=0;b<a.length;b++)a[b].addEventListener("click",this.handleRadioEvent,!0),a[b].addEventListener("keyup",this.handleRadioEvent,!0),a[b].addEventListener("change",function(){jQuery(this).valid()},!0)},handleRadioEvent:function(a){if(a.keyCode>=48&&a.keyCode<=53){var b=a.keyCode-48;jQuery(this).find('input[type="radio"][value='+b+"]").click()}},customValidators:function(){jQuery.validator.addMethod("ratingRequired",function(a,b){return jQuery(b).find("input:checked").val()>0},jQuery.validator.messages.required)},validateForm:function(){var a=jQuery("#wpmtst-submission-form");a.validate({onfocusout:!1,focusInvalid:!1,invalidHandler:function(a,b){var c=b.numberOfInvalids();if(c)if(strongValidation.settings.scroll.onError){if("undefined"!=typeof b.errorList[0]){var d=jQuery(b.errorList[0].element),e=d.closest(".form-field").offset(),f=e.top-strongValidation.settings.scroll.onErrorOffset;jQuery("html, body").animate({scrollTop:f},800,function(){d.focus()})}}else b.errorList[0].element.focus()},submitHandler:function(a){if(strongValidation.disableForm(),""!==strongValidation.settings.ajaxUrl){window.onbeforeunload=function(){return"Please wait while the form is submitted."};var b={url:strongValidation.settings.ajaxUrl,data:{action:"wpmtst_form2"},success:strongValidation.showResponse};jQuery(a).ajaxSubmit(b)}else a.submit()},rules:strongValidation.rules,errorPlacement:function(a,b){a.appendTo(b.closest("div.form-field"))},highlight:function(a,b,c){"checkbox"===a.type?jQuery(a).closest(".field-wrap").addClass(b).removeClass(c):"rating"===jQuery(a).data("fieldType")?jQuery(a).closest(".field-wrap").addClass(b).removeClass(c):jQuery(a).addClass(b).removeClass(c)},unhighlight:function(a,b,c){"checkbox"===a.type?jQuery(a).closest(".field-wrap").removeClass(b).addClass(c):"rating"===jQuery(a).data("fieldType")?jQuery(a).closest(".field-wrap").removeClass(b).addClass(c):jQuery(a).removeClass(b).addClass(c)}})},showResponse:function(a){window.onbeforeunload=null,strongValidation.enableForm();var b=JSON.parse(a);if(b.success)jQuery("#wpmtst-form").html(b.message),strongValidation.scrollOnSuccess();else for(var c in b.errors)b.errors.hasOwnProperty(c)&&jQuery("#wpmtst-submission-form").children(".field-"+c).find("span.error").remove().end().append('<span class="error">'+b.errors[c]+"</span>")},scrollOnSuccess:function(){if(strongValidation.settings.scroll.onSuccess){var a,b;a=jQuery(".wpmtst-testimonial-success").offset(),a&&(b=a.top-strongValidation.settings.scroll.onSuccessOffset,jQuery("#wpadminbar").length&&(b-=32),jQuery("html, body").animate({scrollTop:b},800))}},disableForm:function(){jQuery(".strong-form-wait").show(),jQuery("#wpmtst_submit_testimonial").prop("disabled",!0)},enableForm:function(){jQuery(".strong-form-wait").hide(),jQuery("#wpmtst_submit_testimonial").prop("disabled",!1)}},strongValidation={defaults:{ajaxUrl:"",display:{successMessage:!1},scroll:{onError:!0,onErrorOffset:100,onSuccess:!0,onSuccessOffset:100},fields:{}},settings:{},setOpts:function(a){this.settings=jQuery.extend({},this.defaults,a)},rules:{},setRules:function(){for(var a=0;a<this.settings.fields.length;a++)"rating"===this.settings.fields[a].type&&1===this.settings.fields[a].required&&(this.rules[this.settings.fields[a].name]={ratingRequired:!0})},init:function(){var a={};void 0!==window.strongForm&&(a=window.strongForm),this.setOpts(a),this.settings.display.successMessage?this.scrollOnSuccess():(this.setRules(),this.changeEvents(),this.customValidators(),this.validateForm())},changeEvents:function(){jQuery('input[type="text"], input[type="url"], input[type="email"], textarea',"#wpmtst-submission-form").on("change blur",function(a){a.target.value=a.target.value.trim()}),jQuery("input[type=url]").change(function(){this.value.length&&!/^https*:\/\//.test(this.value)&&(this.value="https://"+this.value)});for(var a=document.getElementsByClassName("strong-rating"),b=0;b<a.length;b++)a[b].addEventListener("click",this.handleRadioEvent,!0),a[b].addEventListener("keyup",this.handleRadioEvent,!0),a[b].addEventListener("change",function(){jQuery(this).valid()},!0)},handleRadioEvent:function(a){if(a.keyCode>=48&&a.keyCode<=53){var b=a.keyCode-48;jQuery(this).find('input[type="radio"][value='+b+"]").click()}},customValidators:function(){jQuery.validator.addMethod("ratingRequired",function(a,b){return jQuery(b).find("input:checked").val()>0},jQuery.validator.messages.required)},validateForm:function(){jQuery("#wpmtst-submission-form").validate({onfocusout:!1,focusInvalid:!1,invalidHandler:function(a,b){if(b.numberOfInvalids())if(strongValidation.settings.scroll.onError){if(void 0!==b.errorList[0]){var c=jQuery(b.errorList[0].element),d=c.closest(".form-field").offset().top-strongValidation.settings.scroll.onErrorOffset;jQuery("html, body").animate({scrollTop:d},800,function(){c.focus()})}}else b.errorList[0].element.focus()},submitHandler:function(a){if(strongValidation.disableForm(),""!==strongValidation.settings.ajaxUrl){window.onbeforeunload=function(){return"Please wait while the form is submitted."};var b={url:strongValidation.settings.ajaxUrl,data:{action:"wpmtst_form2"},success:strongValidation.showResponse};jQuery(a).ajaxSubmit(b)}else a.submit()},rules:strongValidation.rules,errorPlacement:function(a,b){a.appendTo(b.closest("div.form-field"))},highlight:function(a,b,c){"checkbox"===a.type?jQuery(a).closest(".field-wrap").addClass(b).removeClass(c):"rating"===jQuery(a).data("fieldType")?jQuery(a).closest(".field-wrap").addClass(b).removeClass(c):jQuery(a).addClass(b).removeClass(c)},unhighlight:function(a,b,c){"checkbox"===a.type?jQuery(a).closest(".field-wrap").removeClass(b).addClass(c):"rating"===jQuery(a).data("fieldType")?jQuery(a).closest(".field-wrap").removeClass(b).addClass(c):jQuery(a).removeClass(b).addClass(c)}})},showResponse:function(a){window.onbeforeunload=null,strongValidation.enableForm();var b=JSON.parse(a);if(b.success)jQuery("#wpmtst-form").html(b.message),strongValidation.scrollOnSuccess();else for(var c in b.errors)b.errors.hasOwnProperty(c)&&jQuery("#wpmtst-submission-form").children(".field-"+c).find("span.error").remove().end().append('<span class="error">'+b.errors[c]+"</span>")},scrollOnSuccess:function(){var a,b;strongValidation.settings.scroll.onSuccess&&(a=jQuery(".wpmtst-testimonial-success").offset())&&(b=a.top-strongValidation.settings.scroll.onSuccessOffset,jQuery("#wpadminbar").length&&(b-=32),jQuery("html, body").animate({scrollTop:b},800))},disableForm:function(){jQuery(".strong-form-wait").show(),jQuery("#wpmtst_submit_testimonial").prop("disabled",!0)},enableForm:function(){jQuery(".strong-form-wait").hide(),jQuery("#wpmtst_submit_testimonial").prop("disabled",!1)}};
1
+ class strongValidation{constructor(s){this.form=jQuery(s).find("form"),this.formID=this.form.data("formid"),this.defaults={ajaxUrl:"",display:{successMessage:!1},scroll:{onError:!0,onErrorOffset:100,onSuccess:!0,onSuccessOffset:100},fields:{}},this.settings={},this.rules={},this.init()}setOpts(s){this.settings=jQuery.extend({},this.defaults,s)}setRules(){for(var s=0;s<this.settings.fields.length;s++)"rating"===this.settings.fields[s].type&&1===this.settings.fields[s].required&&(this.rules[this.settings.fields[s].name]={ratingRequired:!0})}init(){var s={};void 0!==window.strongForm&&(s=this.form.data("config")),this.setOpts(s),this.settings.display.successMessage?this.scrollOnSuccess():(this.setRules(),this.changeEvents(),this.customValidators(),this.validateForm())}changeEvents(){jQuery('input[type="text"], input[type="url"], input[type="email"], textarea',".wpmtst-submission-form").on("change blur",function(s){s.target.value=s.target.value.trim()}),jQuery("input[type=url]").on("change",function(){this.value.length&&!/^https*:\/\//.test(this.value)&&(this.value="https://"+this.value)});for(var s=document.getElementsByClassName("strong-rating"),e=0;e<s.length;e++)s[e].addEventListener("click",this.handleRadioEvent,!0),s[e].addEventListener("keyup",this.handleRadioEvent,!0),s[e].addEventListener("change",function(){jQuery(this).valid()},!0)}disableForm(){jQuery('.strong-form-wait[data-formid="'+this.formID+'"]').show(),this.form.find(".wpmtst_submit_testimonial").prop("disabled",!0)}enableForm(){jQuery('.strong-form-wait[data-formid="'+this.formID+'"]').hide(),this.form.find(".wpmtst_submit_testimonial").prop("disabled",!1)}handleRadioEvent(s){if(s.keyCode>=48&&s.keyCode<=53){var e=s.keyCode-48;jQuery(this).find('input[type="radio"][value='+e+"]").trigger("click")}}customValidators(){jQuery.validator.addMethod("ratingRequired",function(s,e){return jQuery(e).find("input:checked").val()>0},jQuery.validator.messages.required)}validateForm(){var s=this;this.form.validate({onfocusout:!1,focusInvalid:!1,invalidHandler:function(e,t){if(t.numberOfInvalids())if(s.settings.scroll.onError){if(void 0!==t.errorList[0]){var i=jQuery(t.errorList[0].element),r=i.closest(".form-field").offset().top-s.settings.scroll.onErrorOffset;jQuery("html, body").animate({scrollTop:r},800,function(){i.focus()})}}else t.errorList[0].element.focus()},submitHandler:function(){if(s.disableForm(),""!==s.settings.ajaxUrl){window.onbeforeunload=function(){return"Please wait while the form is submitted."};var e={url:s.settings.ajaxUrl,data:{action:"wpmtst_form2"},success:function(e){s.showResponse(e)}};s.form.ajaxSubmit(e)}else s.form.get(0).submit()},rules:this.rules,errorPlacement:function(s,e){s.appendTo(e.closest("div.form-field"))},highlight:function(s,e,t){"checkbox"===s.type?jQuery(s).closest(".field-wrap").addClass(e).removeClass(t):"rating"===jQuery(s).data("fieldType")?jQuery(s).closest(".field-wrap").addClass(e).removeClass(t):jQuery(s).addClass(e).removeClass(t)},unhighlight:function(s,e,t){"checkbox"===s.type?jQuery(s).closest(".field-wrap").removeClass(e).addClass(t):"rating"===jQuery(s).data("fieldType")?jQuery(s).closest(".field-wrap").removeClass(e).addClass(t):jQuery(s).removeClass(e).addClass(t)}})}showResponse(s){window.onbeforeunload=null,this.enableForm();var e=JSON.parse(s);if(e.success)this.form.parent().html(e.message),this.scrollOnSuccess();else for(var t in e.errors)e.errors.hasOwnProperty(t)&&this.form.children(".field-"+t).find("span.error").remove().end().append('<span class="error">'+e.errors[t]+"</span>")}scrollOnSuccess(){var s,e;this.settings.scroll.onSuccess&&((s=jQuery(".wpmtst-form-id-"+this.formID).find(".wpmtst-testimonial-success").offset())&&(e=s.top-this.settings.scroll.onSuccessOffset,jQuery("#wpadminbar").length&&(e-=32),jQuery("html, body").animate({scrollTop:e},800)))}}
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: testimonials, testimonial slider, testimonial form, star ratings
4
  Requires at least: 5.2
5
  Requires PHP: 5.6
6
  Tested up to: 6.0
7
- Stable tag: 3.0.0
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -207,7 +207,960 @@ No. If you already have testimonials in another plugin or theme, you will have t
207
 
208
  == Changelog ==
209
 
210
- * See [changelog.txt](https://github.com/WPChill/strong-testimonials/blob/dev/changelog.txt) for previous versions.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
 
212
  == Upgrade Notice ==
213
 
4
  Requires at least: 5.2
5
  Requires PHP: 5.6
6
  Tested up to: 6.0
7
+ Stable tag: 3.0.1
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
207
 
208
  == Changelog ==
209
 
210
+ = 3.0.1 - 18.08.2022 -
211
+ - Fixed: strongValidation error on front form ( https://github.com/WPChill/strong-testimonials/issues/326 )
212
+ - Added: Advanced settings tab and logging system
213
+
214
+ = 3.0.0 - 18.07.2022 -
215
+ - Added: Optional parameter to function wpmtst_get_success_message
216
+ - Added: Added an "alt" tag for the submission form's spinner image ( https://github.com/WPChill/strong-testimonials/issues/291 )
217
+ - Fixed: Fatal error in shortcode when decimals attribute from shortcode was not a number but a string
218
+ - Fixed: Small typo on admin side ( https://github.com/WPChill/strong-testimonials/issues/290 )
219
+ - Fixed: Minor escape bug in admin area ( https://github.com/WPChill/strong-testimonials/issues/286 )
220
+ - Changed: Updated jQuery Validate version to 1.19.5 ( https://github.com/WPChill/strong-testimonials/issues/292 )
221
+ - Changed: Updated the "Goodbye" form interface on plugin deactivation ( https://github.com/WPChill/strong-testimonials/issues/308 )
222
+
223
+ = 2.51.9 - 04.04.2022 =
224
+ - Changed: Replaced the Welcome page and now only appears on new/fresh installs
225
+
226
+ = 2.51.8 - 28.03.2022 =
227
+ - Fixed: Added filter to remove Upgrade from PRO when max license ( https://github.com/WPChill/strong-testimonials/issues/305 )
228
+
229
+ = 2.51.7 - 21.03.2022 =
230
+ - Added: Lite vs Pro page ( https://github.com/WPChill/strong-testimonials/issues/167 )
231
+ - Added: Upgrade to PRO action link in the plugins page ( https://github.com/WPChill/strong-testimonials/issues/303 )
232
+
233
+ = 2.51.6 - 15.09.2021 =
234
+ - Fixed upsells for wp 5.8.1 ( https://github.com/WPChill/strong-testimonials/issues/281 )
235
+ - Added: Tracking option - allow us to track non-sensitive data, only information regarding the WordPress environment and Strong Testimonials settings
236
+
237
+ = v2.51.5 - 29/07/2021 =
238
+ - Fixed: Columns and Grid css display bug, removed not needed class from testimonial content
239
+
240
+ = v2.51.5 - 20/07/2021 =
241
+ - Changed: The field for “Company Name” doesn't appear anymore in the list of default fields when creating a new view, if it has been removed via the form editor. ( https://github.com/WPChill/strong-testimonials/issues/240 )
242
+ - Changed: JQuery Strong slider public methods in order to allow users to acces public methods of bxSlider ( https://github.com/WPChill/strong-testimonials/issues/233 )
243
+ - Fixed: The Read More link display bug ( https://github.com/WPChill/strong-testimonials/issues/245 )
244
+ - Fixed: Undefined index ( https://github.com/WPChill/strong-testimonials/issues/249 )
245
+ - Fixed: Incompatibility problem with Swift Performance related to lazy load ( https://github.com/WPChill/strong-testimonials/issues/254 )
246
+ - Fixed: Error on slider arrows on the Wave accesibility report ( https://github.com/WPChill/strong-testimonials/issues/253 )
247
+ - Fixed: Extra pagination ID or slug sanitize issue from View ( https://github.com/WPChill/strong-testimonials/issues/246 )
248
+ - Fixed: Title setting sanitize issue from View ( https://github.com/WPChill/strong-testimonials/issues/241 )
249
+ - Fixed: Unstyled Template issue with grid layout and pagination ( https://github.com/WPChill/strong-testimonials/issues/242 )
250
+ - Fixed: Security fix with input escaping ( https://github.com/WPChill/strong-testimonials/issues/269 )
251
+ - Fixed: Notice when activating the plugin or entering CPT ( https://github.com/WPChill/strong-testimonials/issues/272 )
252
+ - Fixed: Complete data for uninstall process ( https://github.com/WPChill/strong-testimonials/issues/264 )
253
+ - Fixed: Copy shortcode functionality ( https://github.com/WPChill/strong-testimonials/issues/265 )
254
+ - Changed: Upsell messages display ( https://github.com/WPChill/strong-testimonials/issues/262 )
255
+ - Changed: Noopener and Noreferrer links ON by default ( https://github.com/WPChill/strong-testimonials/issues/257 )
256
+ - Fixed: WAVE accessibility report ( https://github.com/WPChill/strong-testimonials/issues/253 )
257
+ - Fixed: Maximum title length ( https://github.com/WPChill/strong-testimonials/issues/256 )
258
+
259
+
260
+
261
+ = v2.51.4 - 11/04/2021 =
262
+ - Fixed: Addded more escapes and sanitization
263
+ - Fixed: Compatibility with PHP8
264
+
265
+
266
+ = v2.51.3 - 16/03/2021 =
267
+ - Changed: View backend in order to be more customizable ( https://github.com/WPChill/strong-testimonials/issues/222 )
268
+ - Added: A class to disabled class for each template ( https://github.com/WPChill/strong-testimonials/issues/210 )
269
+ - Fixed: Incompatibility between DIVI builder and testimonials'excerpt display ( https://github.com/WPChill/strong-testimonials/issues/231 )
270
+ - Fixed: Sanitization issue ( https://github.com/WPChill/strong-testimonials/issues/236 )
271
+
272
+ = v2.51.2 - 24/02/2021 =
273
+ - Fixed: Manual excerpt ( https://github.com/WPChill/strong-testimonials/issues/220 )
274
+
275
+ = v2.51.1 - 18/02/2021 =
276
+ - Fixed: Extensions page CSS.
277
+
278
+ = v2.51.0 - 18/02/2021 =
279
+ - Changed: Added by default review field to ST form ( https://github.com/WPChill/strong-testimonials/issues/199 )
280
+ - Changed: Improved security (https://github.com/WPChill/strong-testimonials/issues/200)
281
+ - Changed: Upsell texts & design (https://github.com/WPChill/strong-testimonials/issues/204 / https://github.com/WPChill/strong-testimonials/issues/201)
282
+ - Fixed: Addon page design (https://github.com/WPChill/strong-testimonials/issues/202)
283
+ - Fixed: How excerpt were handled, now when you click read more the excerpt will hide and we will show only the full content ( https://github.com/WPChill/strong-testimonials/issues/207 )
284
+ - Fixed: Show on Checked Value string without escape characters(/) ( https://github.com/WPChill/strong-testimonials/issues/209 )
285
+ - Fixed: Keep HTML markup in a testimonial post intact ( https://github.com/WPChill/strong-testimonials/issues/206 )
286
+ - Fixed: How RTL work with our slideshow ( https://github.com/WPChill/strong-testimonials/issues/203 )
287
+
288
+ = 2.50.4 =
289
+ * Added Welcome Banner when Strong Testimonials is activated.
290
+ * Removed uninstall message that was appearing in WP dashboard when using multisite network.
291
+ * Removed Lazy Loading Setting for WP versions higher than 5.5 when the core LazyLoad is enabled.
292
+ * Fixed typo from Fields.
293
+
294
+ = 2.50.3 =
295
+ * Fixed upsells option
296
+ * Fixed Slideshow Stretch behaviour.
297
+ * Fixed Slideshow Start automatically behaviour.
298
+ * Fixed expand content in place in sidebar bug.
299
+ * Fixed Strong Testimonials Pro activation from Extensions.
300
+ * Fixed Read More issue when using a testimonial slideshow view in a widget.
301
+ * Replace deprecated filter.
302
+ * Replaced deprecated join with implode.
303
+
304
+ = 2.50.2 =
305
+ * Fixed fatal error
306
+
307
+ = 2.50.1 =
308
+ * Small fixes
309
+ * Changed the layout of the views page.
310
+ * Moved form tab from general settings to Form.
311
+ * Fixed drag and drop issue for testimonials.
312
+ * Added old testimonial-heading CSS classes back.
313
+
314
+ = 2.50.0 =
315
+ * Fixed read more bug
316
+ * Added integration with the new addons
317
+ * Changed email's content type
318
+ * Fixed slider navigation and pagination bug
319
+
320
+ = 2.41.1 =
321
+ * Fixed title option bug from views
322
+ * Fixed continous sliding behavior bug
323
+
324
+ = 2.41.0 =
325
+ * Added support for comments to Testimonials
326
+ * Added options to calculate average rating for multiple ratings
327
+ * Added GDPR integrations
328
+ * Added Star Rating Fieldset Accessibility
329
+ * Added noopener noreferrer option for links
330
+ * Added Lazy Load option in testimonial general settings for testimonials feature images
331
+ * Added upsells option in testimonial general settings to remove upsells from admin area
332
+ * Added characters limit in Forms for testimonial's heading and content
333
+
334
+ * Fixed incompatibility with Metaslider PRO
335
+ * Fixed incompatibility with Simple Custom Post Order
336
+ * Fixed incompatibility with WP Rocket to randomize testimonials
337
+ * Fixed font color bug
338
+
339
+ = 2.40.7 - May 25, 2020 =
340
+ * Fixed pagination buttons
341
+ * Fixed spinner for submitted form
342
+
343
+ = 2.40.6 - Apr. 29, 2020 =
344
+ * Fixed undefined index error
345
+ * Fixed pagination buttons
346
+
347
+ = 2.40.5 - Apr. 16, 2020 =
348
+ * Add old css class back for templates
349
+
350
+ = 2.40.4 - Apr. 16, 2020 =
351
+ * Added the old classes back to keep functionality with users custom css
352
+ * Fixed title display
353
+ * Adressed an issue regarding the company name field
354
+
355
+ = 2.40.3 - Apr. 14, 2020 =
356
+ * Fixed fatal error on testimonials order.
357
+
358
+ = 2.40.2 - Apr. 13, 2020 =
359
+
360
+ * Improved star rating display
361
+ * Added another attribute to average rating shortcode
362
+ * Removed FontAwesome and added svgs
363
+ * Removed banners
364
+ * Update CSS classes with unique prefix
365
+ * Added Uninstall Functionality
366
+ * Removed About Page
367
+ * Fix automatic excerpt for Salient Theme
368
+ * Fix slider arrows for first/last
369
+ * Update notices/tooltips
370
+ * Add functionality to link testimonial to external URL also
371
+ * Reorder now always on - removed setting
372
+ * Added functionality to prevent license inspection
373
+ * Added extra filter `wpmtst_views_actions` in admin/class-strong-view-list-table.php on line 132
374
+
375
+ = 2.40.1 - Jan. 25, 2020 =
376
+ * improved data sanitization
377
+
378
+ = 2.40.0 - Oct. 16, 2019 =
379
+ * improved compatibility with Strong Testimonials: Importer extension
380
+
381
+ = 2.39.3 - Aug. 05, 2019 =
382
+ * removed MIME duplicate header information from the mail sent when submitting a new testimonial
383
+ * improved compatibility with Strong Testimonials: Advanced Views and Pro Templates extensions
384
+ * Fixed warnings ( https://github.com/MachoThemes/strong-testimonials/issues/80 )
385
+
386
+ = 2.39.2 - Jun. 25, 2019 =
387
+ * improved compatibility with Strong Testimonials: Advanced Views extension
388
+
389
+ = 2.39.1 - Jun. 14, 2019 =
390
+ * improved compatibility with Strong Testimonials: Custom Fields extension
391
+
392
+ = 2.39 - May. 24, 2019 =
393
+ * added compatibility with Strong Testimonials: Captcha extension
394
+
395
+ = 2.38.1 - May. 14, 2019 =
396
+ * fixed placeholder issue for standard input fields
397
+ * fixed slideshow height issue
398
+
399
+ = 2.38 - May. 05, 2019 =
400
+ * fixed multiple issues with the `read more` link not expanding the full content
401
+ * fixed an issue with the `read more` link not appearing in some cases
402
+ * fixed an issue with the forms fields not displaying quotation marks correctly
403
+ * fixed an issue with the form textarea not displaying the placeholder correctly
404
+ * fixed a bug where a testimonial view was throwing and error when displaying a url label
405
+
406
+ = 2.37 - Mar. 18, 2019 =
407
+ * added ability to export testimonials with featured images included.
408
+ * added option to change single testimonial permalink slug.
409
+ * fixed a conflict with `Mesmerize` theme not displaying the views.
410
+ * fixed issue with audio shortcode not playing in the testimonial content.
411
+ * fixed form redirect url not saving.
412
+ * fixed issue when testimonial slideshows has only one testimonial.
413
+ * fixed issue with the `read more` link in a slideshow not toggling correctly.
414
+ * removed `Really Simple Captcha` from captcha settings.
415
+ * fixed wp_debug warnings.
416
+ * minor backend tweaks.
417
+
418
+ = 2.36 - Feb. 15, 2019 =
419
+ * bug fixes and tweaks
420
+
421
+ = 2.35 - Feb. 12, 2019 =
422
+ * fixed multiple bugs with the submission form
423
+ * fixes testimonial and star rating not displaying properly
424
+
425
+ = 2.34 - Feb. 8, 2019 =
426
+ * removed all strongplugins.com branding
427
+ * removed links to external addons; all Strong Testimonials addons should be delivered from w.org
428
+ * re-licensed under GPLv3 & added a copy of the license in .txt format
429
+ * improved plugin escaping / sanitization
430
+
431
+ = 2.32.4 - Dec. 27, 2018 =
432
+ * Prerender shortcodes in WordPress Custom HTML widgets.
433
+
434
+ = 2.32.3 - Dec 4, 2018 =
435
+ * Fix stretched slide height in carousel.
436
+
437
+ = 2.32.2 - Dec 4, 2018 =
438
+ * Add adjustable responsive breakpoints for carousels.
439
+
440
+ = 2.32.1 - Oct 26, 2018 =
441
+ * Fix bug in translation of slider text controls.
442
+
443
+ = 2.32 - Aug 6, 2018 =
444
+ * Add carousel option.
445
+ * Add filters to form field classes.
446
+
447
+ = 2.31.10 - Aug 2, 2018 =
448
+ * Fix singular/plural phrases in testimonial average shortcode.
449
+ * Fix bug in scroll to success message.
450
+ * Fix RTL slider controls.
451
+ * Attempt to fix slider touch problems in iOS.
452
+
453
+ = 2.31.9 - July 17, 2018 =
454
+ * Fix compatbility issue with Gutenberg.
455
+ * Fix bug in average rating calculation.
456
+ * Fix CSS columns for recent browser updates.
457
+ * Fix bug in lazy-loading compatibility option.
458
+ * Improve theme compatibility.
459
+ * Add filter on form submit button CSS class.
460
+
461
+ = 2.31.8 - June 16, 2018 =
462
+ * Fix "wait" spinner in unstyled form template.
463
+ * On forms, only show required symbol if field label is shown.
464
+ * Refactor inline style method.
465
+ * Improve exception handling.
466
+
467
+ = 2.31.7 - June 7, 2018 =
468
+ * Fix JavaScript incompatibility in IE and Edge.
469
+
470
+ = 2.31.6 - June 2, 2018 =
471
+ * Fix bug when adding a custom field in view editor.
472
+
473
+ = 2.31.5 - June 1, 2018 =
474
+ * Fix XSS vulnerablilities reported by DefenseCode using Thunderscan.
475
+ * Add spinner UI element while form is being submitted to deter visitor from navigating away.
476
+ * Minor admin UI improvements.
477
+
478
+ = 2.31.4 - May 22, 2018 =
479
+ * Add integration with WordPress privacy exporter and eraser features.
480
+
481
+ = 2.31.3 - May 19, 2018 =
482
+ * Fix missing submit button.
483
+
484
+ = 2.31.2 - May 18, 2018 =
485
+ * Fix bug in average rating half-star.
486
+
487
+ = 2.31.1 - May 15, 2018 =
488
+ * Fix conflict with Review Markup add-on.
489
+
490
+ = 2.31 - May 15, 2018 =
491
+ * Add `[testimonial_average_rating]` shortcode.
492
+ * Add compatibility option for script controller.
493
+ * Add compatibility option for lazy loading images.
494
+ * Minor template style tweaks for small screens.
495
+ * Use empty star icon instead of full icon in different color.
496
+ * Change default message "Required field" to "Required".
497
+ * Improve exception handling.
498
+ * Improve Pjax compatibility.
499
+ * Apply JavaScript coding standard.
500
+ * Add console logging for slider when `SCRIPT_DEBUG` enabled.
501
+ * Minor admin style tweaks.
502
+
503
+ = 2.30.9 - May 6, 2018 =
504
+ * Fix bug in add-on activation process.
505
+
506
+ = 2.30.8 - April 26, 2018 =
507
+ * Fix incorrect text domains.
508
+ * Fix bug in form validation translation files.
509
+ * Remove obsolete German translation.
510
+ * Update translation files.
511
+ * Refactor the submit buttons on settings pages.
512
+
513
+ = 2.30.7 - April 23, 2018 =
514
+ * Fix bug in front-end controller script.
515
+
516
+ = 2.30.6 - April 17, 2018 =
517
+ * Improve embeds in Masonry layout.
518
+ * Fix `[testimonial_count category]` shortcode in Properties add-on.
519
+ * Update the EDD license updater class.
520
+ * Improve notification email admin UI.
521
+ * Improve notification email message when custom fields are blank.
522
+
523
+ = 2.30.5 - April 9, 2018 =
524
+ * Fix bug when email field is not required.
525
+ * Fix display of templates in view editor when theme/add-on templates are present.
526
+ * Fix inconsistent use of filter on default view settings.
527
+ * Improve compatibility with themes and thumbnail column in admin list.
528
+ * Improve compatibility with installation scripts (table creation).
529
+ * Improve check for missing add-on license.
530
+ * Add front-end "Nothing found" message for administrators.
531
+ * Add data attribute 'count' for found_posts to view container for troubleshooting.
532
+ * Add filter on `[testimonial_count]` shortcode defaults.
533
+ * Add ability to capture notification email on localhost.
534
+ * Revive a logger class.
535
+ * Minor admin UI tweaks.
536
+
537
+ = 2.30.4 - Mar 20, 2018 =
538
+ * Fix bug in slider in Firefox 59.
539
+
540
+ = 2.30.3 - Mar 16, 2018 =
541
+ * Improve slider script compatibility (event propagation).
542
+
543
+ = 2.30.2 - Mar 11, 2018 =
544
+ * Fix backwards-compatibility for WordPress versions 4.5 and older.
545
+
546
+ = 2.30.1 - Mar 6, 2018 =
547
+ * Fix minor bug in PHP7 compatibility.
548
+ * Improve real-time validation in fields editor.
549
+ * Minor CSS fixes.
550
+
551
+ = 2.30.0 - Feb 10, 2018 =
552
+ * Add option for font color in view editor.
553
+ * Add option for a custom CSS class on the image link for lightboxes.
554
+ * Add shortcode attributes for post_ids, category, order, and count.
555
+ * Use `is_email()` to validate email addresses.
556
+ * Use `number_format_i18n()` in testimonial_count shortcode.
557
+ * Refactor template groups into base templates with options.
558
+ * Add option to disable touch swipe navigation in slideshows.
559
+ * Simplify slideshow CSS.
560
+ * Fix bug in slider script in Chrome.
561
+
562
+ = 2.29.1 - Jan 8, 2018 =
563
+ * Only to trigger update because the SVN version was incomplete.
564
+
565
+ = 2.29 - Jan 8, 2018 =
566
+ * Add integration with Google Captcha by BestWebSoft.
567
+ * Remove integration with Captcha plugin.
568
+ * Remove integration with Advanced noCaptcha reCaptcha plugin.
569
+ * Fix CSS conflict with Cherry Slider.
570
+ * Fix bug when adding the category field to the notification email.
571
+ * Fix read-more filter usage for WPML and Polylang.
572
+ * Add filter: `wpmtst_read_more_page_output`.
573
+ * Add support for FooBox Image Lightbox.
574
+ * Improved the notification email admin UI.
575
+ * Handle form submission on custom action.
576
+ * Add dismissible persistent admin notice capability.
577
+ * Improve add-on configuration check.
578
+ * Minor refactoring for improved performance.
579
+
580
+ = 2.28.4 - Nov 20, 2017 =
581
+ * Fix bug when using count in views.
582
+ * Fix bug that prevented saving views.
583
+ * Fix bug that prevented deleting the plugin.
584
+ * Rename the form's submit button CSS class to `wpmtst-submit` to prevent conflicts. Thanks @chestozo.
585
+ * Remove mail debug logger.
586
+ * Improved update process to prevent simultaneous execution.
587
+
588
+ = 2.28.3 - Nov 18, 2017 =
589
+ * Fix bug in slider when not using transition effect.
590
+ * Fix conflict between standard pagination and query limit.
591
+ * Fix bug when saving custom fields in post editor.
592
+ * Add capability for custom input fields.
593
+
594
+ = 2.28.2 - Nov 10, 2017 =
595
+ * Fix bug when only one page in paginated views (count < per_page).
596
+
597
+ = 2.28.1 - Nov 10, 2017 =
598
+ * Fix conflict with paginated views in some themes.
599
+
600
+ = 2.28 - Nov 9, 2017 =
601
+ * Add compatibility settings for Ajax page loading.
602
+ * Add subtle transition effect for paginated views.
603
+ * Add standard pagination options.
604
+ * Previous/Next links
605
+ * Condensed navigation
606
+ * Before/after page number text
607
+ * Fix bug where standard pagination failed to add a trailing slash.
608
+ * Fix bug that failed to check plugin-specific capabilities in multisite.
609
+ * Fix bug that caused redirect loop if database error occurs during installation.
610
+ * Add a JavaScript controller to coordinate components.
611
+ * Refactor slider script.
612
+ * Refactor pager script.
613
+ * Refactor honeypots to inline, plain JavaScript.
614
+ * Refactor many functions into classes.
615
+ * Add ability to register a custom field type (experimental).
616
+
617
+ = 2.27.2 - Oct 10, 2017 =
618
+ * Fix bug in update process.
619
+
620
+ = 2.27.1 - Oct 9, 2017 =
621
+ * Fix bug in update process.
622
+
623
+ = 2.27 - Oct 9, 2017 =
624
+ * Fix optional loading of Font Awesome.
625
+ * Fix width on double-digit pagination controls in Modern template.
626
+ * Fix hiding slider controls if no slides are present.
627
+ * Fix CSS for slider controls in Internet Explorer 11.
628
+ * Add unique user capabilities for workflow control.
629
+ * Add option to set checkbox field on by default.
630
+ * Add option to exclude from Lazy Loading Responsive Images plugin (on by default).
631
+ * Add filters to "Read more" link text and URL.
632
+ * Add filter to form redirect URL.
633
+ * Add filter to skip prerender (for compatibility).
634
+ * Add filters for styles, scripts and script vars.
635
+ * New About page.
636
+ * Minor refactoring for improved performance.
637
+
638
+ = 2.26.10 - Sep 12, 2017 =
639
+ * Fix compatibility with Captcha by simplywordpress 4.3.4+.
640
+ * Fix compatibility with Polylang string translations when user's admin language is not English.
641
+ * Improve flex grid style when last row is less than full.
642
+ * Improve rendering of shortcode field type.
643
+ * Add post ID of newly submitted testimonial to action hook.
644
+
645
+ = 2.26.9 - Sep 2, 2017 =
646
+ * Fix integration with Polylang 2.1+.
647
+ * Indent subcategories in the category selector on the form.
648
+
649
+ = 2.26.8 - Aug 26, 2017 =
650
+ * Fix form whitespace problem in some themes.
651
+
652
+ = 2.26.7 - Aug 15, 2017 =
653
+ * Fix compatibility with Captcha plugin version 4.3.1.
654
+
655
+ = 2.26.6 - Aug 15, 2017 =
656
+ * Trim leading and trailing spaces on form input values.
657
+
658
+ = 2.26.5 - Aug 2, 2017 =
659
+ * Improve adding thumbnail support.
660
+
661
+ = 2.26.4 - July 31, 2017 =
662
+ * Fix bug in WPML String Translations.
663
+
664
+ = 2.26.3 - July 27, 2017 =
665
+ * Fix bug when displaying empty rating in post editor.
666
+
667
+ = 2.26.2 - July 24, 2017 =
668
+ * Fix WPGlobus compatibility.
669
+
670
+ = 2.26.1 - July 17, 2017 =
671
+ * Fix bug in saving checkbox field.
672
+
673
+ = 2.26 - July 6, 2017 =
674
+ * Improve excerpt handling.
675
+ * Add option for linking title to testimonial post.
676
+ * Improve featured image responsive style.
677
+ * Minor UI improvements in view editor.
678
+
679
+ = 2.25.2 - June 28, 2017 =
680
+ * Fix conflict with OptimizePress page builder.
681
+ * Remove defer on admin scripts.
682
+
683
+ = 2.25.1 - June 26, 2017 =
684
+ * Fix bug when adding star rating to single template and category archive.
685
+
686
+ = 2.25 - June 23, 2017 =
687
+ * Improve form validation.
688
+ * Update jQuery Validation plugin (1.16.0).
689
+ * Add tabindex.
690
+ * Add custom validation to star rating field.
691
+ * Improve form error indicator style.
692
+ * Fix bug that was printing duplicate script variables.
693
+ * Make checkbox field text translatable.
694
+ * Add hooks and filters in form submission.
695
+ * Add option to disable "* Required Field" notice.
696
+ * Update link to wordpress.org review form.
697
+ * Update style for Review Markup add-on.
698
+ * Lint and compress JavaScript files.
699
+
700
+ = 2.24 - June 12, 2017 =
701
+ * Fix bug in saving a zero rating.
702
+ * Fix bug in add-on license activation screen.
703
+ * Add real-time configuration checks.
704
+ * Improve debug logger.
705
+
706
+ = 2.23.2 - June 7, 2017 =
707
+ * Fix default translation filters.
708
+
709
+ = 2.23.1 - June 4, 2017 =
710
+ * Fix bug in default nofollow links.
711
+ * Fix bug when saving checkbox value in post editor.
712
+ * fix bug in admin list checkbox column.
713
+
714
+ = 2.23 - May 31, 2017 =
715
+ * Add nofollow default setting.
716
+ * Add checkbox input type.
717
+ * Add support for Captcha Pro by BestWebSoft.
718
+ * Defer front-end javascript to improve compatibility.
719
+ * Allow shortcodes and basic HTML in the "Before", "After", "Text" fields.
720
+ * Add filter on "Required Field" notice.
721
+ * Remove `link_new_tab` and `link_nofollow` functions.
722
+ * Minor refactoring.
723
+
724
+ = 2.22.6 - May 29, 2017 =
725
+ * Fix conflict with prerender and some themes.
726
+
727
+ = 2.22.5 - May 25, 2017 =
728
+ * Fix bug in adding nofollow attribute to outbound links.
729
+
730
+ = 2.22.4 - May 20, 2017 =
731
+ * Fix compatibility with Max Mega Menu plugin.
732
+
733
+ = 2.22.3 - May 18, 2017 =
734
+ * Improve style and script loading.
735
+ * Fix bug in slideshow in WordPress version less than 4.6.
736
+ * Fix WPML slug translation.
737
+ * Minor refactoring.
738
+
739
+ = 2.22.2 - May 14, 2017 =
740
+ * Fix bug in add-on license activation for localhost sites.
741
+
742
+ = 2.22.1 - May 11, 2017 =
743
+ * Fix bug in displaying add-on sections in view editor.
744
+
745
+ = 2.22 - May 9, 2017 =
746
+ * Add option for sticky views.
747
+ * Add view mode for single post template.
748
+ * Add view mode description.
749
+ * Move custom style to `<head>` to avoid FUOC.
750
+ * Use built-in `imagesLoaded` script instead.
751
+ * Move manual excerpt read-more to appear after testimonial content.
752
+ * Fix bug that caused some double read-more's.
753
+ * Improve compatibility with Divi Builder 2.
754
+ * Remove general compatibility mode; no longer needed.
755
+
756
+ = 2.21.2 - Apr 21, 2017 =
757
+ * Fix bug in add-on license activation process.
758
+
759
+ = 2.21.1 - Apr 18, 2017 =
760
+ * Fix bug in Font Awesome loading.
761
+
762
+ = 2.21 - Apr 14, 2017 =
763
+ * Add option for default rating value on the form.
764
+ * Add custom field name to form HTML elements.
765
+ * Add option to skip loading Font Awesome.
766
+ * Add background color option to the form.
767
+ * Add filters to bypass layout stylesheets if not needed.
768
+ * Minor admin UI improvements.
769
+
770
+ = 2.20 - Apr 3, 2017 =
771
+ * Handle screen resize and orientation change in slider.
772
+ * Add `wpautop` to automatic excerpts for consistent style.
773
+ * Improve form nonce check.
774
+ * Update EDD integration.
775
+ * Add filters for custom sort order.
776
+
777
+ = 2.19.2 - Mar 27, 2017 =
778
+ * Fix conflict with Wonderflux framework.
779
+
780
+ = 2.19.1 - Mar 24, 2017 =
781
+ * Fix bug in category assignment on new submissions.
782
+ * Add `wpmtst_field_value` filter.
783
+
784
+ = 2.19 - Mar 18, 2017 =
785
+ * Improve add-on integration.
786
+ * Prevent conflict between Advanced noCaptcha reCaptcha plugin and page builders.
787
+ * Add simple WP-CLI compatibility.
788
+ * Add option to clear star rating value.
789
+
790
+ = 2.18.2 - Feb 26, 2017 =
791
+ * Fix bug in conditional loading of star rating stylesheet.
792
+
793
+ = 2.18.1 - Feb 23, 2017 =
794
+ * Fix bug in form success/error scrolling.
795
+
796
+ = 2.18 - Feb 15, 2017 =
797
+ * Add form success redirect options.
798
+ * Add visual editor (TinyMCE) to the form success message.
799
+ * Process shortcodes in the form success message.
800
+ * Fix bug when slideshows are in hidden tabs.
801
+ * Fix bug in edit rating script.
802
+ * Improve Modern template responsive style.
803
+ * Minor refactoring.
804
+
805
+ = 2.17.5 - Jan 18, 2017 =
806
+ * Fix bug when page has multiple slideshows.
807
+
808
+ = 2.17.4 - Jan 17, 2017 =
809
+ * Fix bug in form Ajax.
810
+
811
+ = 2.17.3 - Dec 28, 2016 =
812
+ * Fix bug that allowed unsanitized custom field names.
813
+ * Improve admin UI.
814
+ * Update Spanish translation.
815
+
816
+ = 2.17.2 - Dec 14, 2016 =
817
+ * Fix incomplete loading of FontAwesome for slideshows.
818
+
819
+ = 2.17.1 - Dec 14, 2016 =
820
+ * Fix bug in plugin activation process.
821
+ * Improve category checklist style in default form template.
822
+
823
+ = 2.17 - Dec 13, 2016 =
824
+ * Add category checklist option to form fields.
825
+ * Fix bug that allowed double underscores in custom field name.
826
+ * Fix date column formatting in testimonials admin list.
827
+ * Improve admin UI in fields and view editors.
828
+ * Improve slideshow controls style.
829
+
830
+ = 2.16.5 - Dec 8, 2015 =
831
+ * Fix bug when [Max Mega Menu](https://wordpress.org/plugins/megamenu/) plugin installed.
832
+
833
+ = 2.16.4 - Dec 7, 2016 =
834
+ * Fix conflict with [Huge IT Slider](https://wordpress.org/plugins/slider-image/) plugin.
835
+ * Remove some unnecessary edge case functions.
836
+
837
+ = 2.16.3 - Dec 5, 2016 =
838
+ * Fix bug when loading form validation translation files.
839
+ * Fix bug that initialized slideshows before images are loaded.
840
+ * Improve admin UI.
841
+
842
+ = 2.16.2 - Dec 4, 2016 =
843
+ * Strip slashes from custom fields and submitted form values.
844
+
845
+ = 2.16.1 - Dec 2, 2016 =
846
+ * Fix bug in slideshow query.
847
+ * Fix conflict with Dream Theme themes.
848
+
849
+ = 2.16 - Dec 1, 2016 =
850
+ * Fix missing icons (start, quotes, pager buttons).
851
+ * Fix incorrect WPML string registration (read-more texts).
852
+ * Improve compatibility.
853
+
854
+ = 2.15 - Nov 29, 2016 =
855
+ * Add 'required' attribute to file input field.
856
+ * Add slideshow behavior options.
857
+ * Add slideshow control and navigation options.
858
+ * Fix minor bugs.
859
+
860
+ = 2.14.3 - Nov 22, 2016 =
861
+ * Fix reordering.
862
+ * Fix rating column in admin list.
863
+ * Add post type and taxonomy filters.
864
+ * Improve upgrade process.
865
+
866
+ = 2.14.2 - Nov 3, 2016 =
867
+ * Fix bug in form validation.
868
+
869
+ = 2.14.1 - Nov 1, 2016 =
870
+ * Fix bug in non-paginated query.
871
+
872
+ = 2.14 - Oct 31, 2016 =
873
+ * Add option for using standard WordPress pagination.
874
+ * Add option for displaying text before a custom field.
875
+ * Redesign fields section in view editor.
876
+ * Begin conversion to SCSS.
877
+ * Improve contextual help and links.
878
+ * Improve compatibility and performance.
879
+
880
+ = 2.13.5 - Oct 22, 2016 =
881
+ * Fix loading of FontAwesome.
882
+
883
+ = 2.13.4 - Oct 20, 2016 =
884
+ * Fix bug in loading view resources.
885
+ * Fix bug in pagination settings.
886
+ * Fix bug in mail queue.
887
+ * Handle multiple paginated views on same page.
888
+ * Handle multiple rating fields.
889
+
890
+ = 2.13 - Oct 17, 2016 =
891
+ * Fix bug in saving star rating in post editor.
892
+ * Fix bug when clearing a URL field.
893
+ * Fix bug in redisplaying form values when form has errors.
894
+ * Add options for scrolling to the form success message or first form error.
895
+
896
+ = 2.12.4 - Sep 28, 2016 =
897
+ * Add title to Modern template.
898
+ * Fix left-aligned image in Modern template in some themes.
899
+ * Fix conflict with Styles: Twentyfourteen plugin.
900
+
901
+ = 2.12.3 - Sep 23, 2016 =
902
+ * Enforce email and URL input types.
903
+
904
+ = 2.12.2 - Sep 15, 2016 =
905
+ * Fix compatibility with versions of WordPress before 4.4.
906
+ * Fix bug in fields editor.
907
+ * Remove disabling of title, thumbnail, and category fields in view editor if those fields were not found in form fields.
908
+
909
+ = 2.12.1 - Sep 15, 2016 =
910
+ * Fix bug in loading Font Awesome.
911
+ * Fix bug in new submit_date field.
912
+ * Fix bug in form preview.
913
+
914
+ = 2.12 - Sep 14, 2016 =
915
+ * Star ratings!
916
+ * Get rating on a form
917
+ * Display in a view
918
+ * Edit on the testimonial
919
+ * Show in admin list
920
+ * Store the date a testimonial was submitted for displaying in a view.
921
+ * Improve fields:
922
+ * Add form preview.
923
+ * Add contextual help (the Help tab).
924
+ * Add option to hide the label.
925
+ * Add option for default form value (translatable).
926
+ * Add option for default display value (translatable).
927
+ * Add option to include a shortcode.
928
+ * Fix bug: Save fields after restoring defaults.
929
+ * Improve fields editor UI.
930
+ * Add feature to copy the testimonial shortcode to the clipboard.
931
+ * Fix function that checks for minimum required WordPress version.
932
+ * Remove unused Font Awesome files.
933
+ * Update POT file.
934
+ * Minor refactoring.
935
+
936
+ = 2.11.17 - Sep 8, 2016 =
937
+ * Add "Read more" link text to WPML and Polylang translation strings.
938
+
939
+ = 2.11.16 - Sep 3, 2016 =
940
+ * Fix conflict with [Styles](https://wordpress.org/plugins/styles/) plugin.
941
+
942
+ = 2.11.15 - Sep 2, 2016 =
943
+ * Fix bug in menu for subscribers.
944
+
945
+ = 2.11.14 - Aug 25, 2016 =
946
+ * Handle special characters in view name.
947
+
948
+ = 2.11.13 - Aug 24, 2016 =
949
+ * Improve theme compatibility.
950
+
951
+ = 2.11.12 - Aug 22, 2016 =
952
+ * Fix bug in loading Font Awesome for Modern template.
953
+
954
+ = 2.11.11 - Aug 19, 2016 =
955
+ * Fix custom image size.
956
+
957
+ = 2.11.10 - Aug 19, 2016 =
958
+ * Improve general theme compatibility.
959
+
960
+ = 2.11.9 - Aug 13, 2016 =
961
+ * Improve compatibility with [CM Tooltip Glossary](https://wordpress.org/plugins/enhanced-tooltipglossary/).
962
+
963
+ = 2.11.8 - Aug 11, 2016 =
964
+ * Maintain line breaks in submitted testimonial content.
965
+
966
+ = 2.11.7 - Aug 10, 2016 =
967
+ * Remove `wp_make_content_images_responsive` filter.
968
+
969
+ = 2.11.6 - Aug 10, 2016 =
970
+ * Remove `wp_make_content_images_responsive` filter.
971
+
972
+ = 2.11.5 - Aug 10, 2016 =
973
+ * Compatible with [CM Tooltip Glossary](https://wordpress.org/plugins/enhanced-tooltipglossary/).
974
+ * Reinstate option for "Read more" link to a page from within testimonial.
975
+
976
+ = 2.11.4 - Aug 9, 2016 =
977
+ * Reinstate "Read more" option for manual excerpts.
978
+
979
+ = 2.11.3 - July 25, 2016 =
980
+ * Remove background on Modern template.
981
+
982
+ = 2.11.2 - July 20, 2016 =
983
+ * New template: Modern.
984
+
985
+ = 2.11.1 - July 20, 2016 =
986
+ * Fix bug in pagination.
987
+ * Fix bug in view class name option.
988
+
989
+ = 2.11 - July 19, 2016 =
990
+ * Slideshow navigation options.
991
+
992
+ = 2.10.3 - July 13, 2016 =
993
+ * Fix conflict with NextGEN Gallery.
994
+ * Fix bugs in update process.
995
+ * Add `wpmtst_before_testimonial` and `wpmtst_after_testimonial` hooks for prepending and appending content to each testimonial.
996
+
997
+ = 2.10.2 - July 12, 2016 =
998
+ * Fix bug in "Read more" selector.
999
+
1000
+ = 2.10.1 - July 11, 2016 =
1001
+ * Fix bug in single testimonial selector.
1002
+
1003
+ = 2.10 - July 11, 2016 =
1004
+ * Fix bug when not using company_website field.
1005
+ * Improve "Read more" link to behave like standard blog posts.
1006
+ * Separate option for a "Read more" link to a page/post.
1007
+ * Option to show an indicator bubble for pending testimonials.
1008
+ * Include Font Awesome instead of loading via CDN.
1009
+
1010
+ = 2.9.4 - July 2, 2016 =
1011
+ * Compatible with FooBox Image Lightbox [Free](https://wordpress.org/plugins/foobox-image-lightbox/) and [Pro](http://fooplugins.com/plugins/foobox/) versions.
1012
+
1013
+ = 2.9.3 - June 28, 2016 =
1014
+ * Fix conflict with themes and plugins that also include Font Awesome.
1015
+
1016
+ = 2.9.2 - June 28, 2016 =
1017
+ * Fix bug.
1018
+
1019
+ = 2.9.1 - June 28, 2016 =
1020
+ * Fix conflict with WooCommerce.
1021
+
1022
+ = 2.9 - June 3, 2016 =
1023
+ * Compatible with [Max Mega Menu](https://wordpress.org/plugins/megamenu/) plugin.
1024
+ * Disable redirect to Guide page after update.
1025
+ * Disable console log output in Cycle script.
1026
+
1027
+ = 2.8 =
1028
+
1029
+ = 2.7 =
1030
+
1031
+ = 2.6 - May 17, 2016 =
1032
+ * Bypass WordPress empty post check.
1033
+ * Enable embeds (YouTube, Twitter, etc.).
1034
+ * Add setting for embed frame width.
1035
+
1036
+ = 2.5.8 - May 12, 2016 =
1037
+ * Fix grid layout in IE 9 and IE 11.
1038
+
1039
+ = 2.5.7 - May 11, 2016 =
1040
+ * New "No Quotes" template.
1041
+ * Restrict the CSS Classes setting to names only; not to be used for custom CSS rules.
1042
+ * Update the Guide.
1043
+
1044
+ = 2.5.6 - April 24, 2016 =
1045
+ * Compatible with [Bretheon](http://themes.muffingroup.com/?theme=bretheon) theme.
1046
+ * Update the Guide.
1047
+
1048
+ = 2.5.5 - April 22, 2016 =
1049
+ * Fix bug in notification email logging.
1050
+ * Fix bug when enabling custom fields and comments.
1051
+
1052
+ = 2.5.4 - April 22, 2016 =
1053
+ * Fix bug in Guide.
1054
+ * Minimum WordPress version required: 3.6.
1055
+
1056
+ = 2.5.3 - April 21, 2016 =
1057
+ * Minor admin UI improvements.
1058
+
1059
+ = 2.5.2 - April 12, 2016 =
1060
+ * Add pagination to `strong_testimonials_view()` template function.
1061
+ * Fix bug in Categories column.
1062
+
1063
+ = 2.5.1 - April 8, 2016 =
1064
+ * Add comments column to testimonial admin list.
1065
+ * Fix conflict with NextGEN Gallery.
1066
+
1067
+ = 2.5 - April 7, 2016 =
1068
+ * Fix bug on date format conversion.
1069
+ * Fix content class bug.
1070
+ * Add filters to override default pagination.
1071
+
1072
+ = 2.4.1 - April 5, 2016 =
1073
+ * Apply all content filters (revert change in 2.4.0).
1074
+ * Bypass content filter for [All In On Schema.org Rich Snippets](https://wordpress.org/plugins/all-in-one-schemaorg-rich-snippets/) plugin.
1075
+
1076
+ = 2.4 - April 4, 2016 =
1077
+ * Add email notification troubleshooting log.
1078
+ * Add option to show Custom Fields meta box.
1079
+ * Add option to enable comments on individual testimonials.
1080
+ * Fix formatting of non-US date formats.
1081
+ * Apply only standard content filters (wptexturize, convert_smilies, wpautop, shortcode_unautop, do_shortcode).
1082
+
1083
+ = 2.3.3 - March 18, 2016 =
1084
+ * Prevent incompatible combination of pagination and Masonry.
1085
+
1086
+ = 2.3.2 - March 17, 2016 =
1087
+ * Fix bug when getting fields for Polylang.
1088
+
1089
+ = 2.3.1 - March 12, 2016 =
1090
+ * Apply all content filters to be compatible with [WPGlobus](https://wordpress.org/plugins/wpglobus/) translation plugin.
1091
+
1092
+ = 2.3 - March 9, 2016 =
1093
+ * Improve compatibility with [Posts for Page](https://wordpress.org/plugins/posts-for-page/), [Custom Content Shortcode](https://wordpress.org/plugins/custom-content-shortcode/), and other plugins that use shortcodes to pull in other content.
1094
+ * Add form handling to `strong_testimonials_view()` template function.
1095
+ * Optimize slideshow loading.
1096
+ * Strip HTML whitespace by default with option to disable.
1097
+ * Disable form honeypots by default in new installs.
1098
+ * Fix bug with first slide in Cycle script.
1099
+ * Fix conflict with RT Themes.
1100
+ * Fix admin style conflict.
1101
+
1102
+ = 2.2.12 - March 3, 2016 =
1103
+ * Fix bug when title is empty in some languages.
1104
+ * Add error logging to save process.
1105
+
1106
+ = 2.2.11 - March 2, 2016 =
1107
+ * Fix slideshow stacking bug in unstyled template.
1108
+ * Add option to disable scroll top in paginated Views.
1109
+
1110
+ = 2.2.10 - March 1, 2016 =
1111
+ * Add post date to Custom Fields in View editor.
1112
+
1113
+ = 2.2.9 - February 29, 2016 =
1114
+ * Fix conflict with [Toolset Views](https://wp-types.com/) plugin.
1115
+ * Add Persian translation.
1116
+
1117
+ = 2.2.8 - February 23, 2016 =
1118
+ * Fix conflict with Post Types Order plugin.
1119
+
1120
+ = 2.2.7 - February 22, 2016 =
1121
+ * Bug fix for PHP 7.
1122
+
1123
+ = 2.2.6 - February 19, 2016 =
1124
+ * Allow some HTML in form messages (same as comments).
1125
+ * Add `wpmtst_form_success_message` filter.
1126
+
1127
+ = 2.2.5 - February 17, 2016 =
1128
+ * Handle possibility of missing standard image sizes.
1129
+
1130
+ = 2.2.4 - February 15, 2016 =
1131
+ * Fix bug in widget processing.
1132
+
1133
+ = 2.2.3 - February 11, 2016 =
1134
+ * Fix bug in category selector in WPML.
1135
+
1136
+ = 2.2.2 - February 10, 2016 =
1137
+ * Fix bug in category selector custom field when localized.
1138
+
1139
+ = 2.2.1 - February 8, 2016 =
1140
+ * Fix bug in View category selector.
1141
+ * Prevent potential class name conflict.
1142
+
1143
+ = 2.2 - February 8, 2016 =
1144
+ * Improve category selector in View editor.
1145
+ * Add category filter to testimonial admin list.
1146
+ * Make category column sortable in testimonial admin list.
1147
+ * Add German translation.
1148
+
1149
+ = 2.1 - February 5, 2016 =
1150
+ * Add ability to duplicate a View.
1151
+ * Fix pagination/slideshow show/hide behavior in View editor.
1152
+ * Add framework for add-on plugins.
1153
+
1154
+ = 2.0.1 - February 3, 2016 =
1155
+ * Fix bug that restored default custom fields.
1156
+
1157
+ = 2.0 - February 2, 2016 =
1158
+ * Remove `[strong]`, `[wpmtst]`, `[read_more]` shortcodes.
1159
+ * Remove original widget.
1160
+ * Add content area to View widget.
1161
+ * Improve handling of special characters in Fields editor.
1162
+ * Fix bug in failed Captcha when submitting form via Ajax.
1163
+ * Compatible with [Profit Builder](http://wpprofitbuilder.com/) plugin.
1164
 
1165
  == Upgrade Notice ==
1166
 
strong-testimonials.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Collect and display your testimonials or reviews.
6
  * Author: WPChill
7
  * Author URI: https://wpchill.com/
8
- * Version: 3.0.0
9
  * Text Domain: strong-testimonials
10
  * Domain Path: /languages
11
  * Requires: 4.6 or higher
@@ -45,9 +45,10 @@ if ( ! defined( 'ABSPATH' ) ) {
45
  exit;
46
  }
47
 
48
- define( 'WPMTST_VERSION', '3.0.0' );
49
  define( 'WPMTST_PLUGIN', plugin_basename( __FILE__ ) ); // strong-testimonials/strong-testimonials.php
50
  define( 'WPMTST', dirname( WPMTST_PLUGIN ) ); // strong-testimonials
 
51
  defined( 'WPMTST_STORE_URL' ) || define( 'WPMTST_STORE_URL', 'https://strongtestimonials.com' );
52
  defined( 'WPMTST_STORE_UPGRADE_URL' ) || define( 'WPMTST_STORE_UPGRADE_URL', 'https://strongtestimonials.com/pricing' );
53
 
@@ -229,6 +230,7 @@ final class Strong_Testimonials {
229
  * @return void
230
  */
231
  private function includes() {
 
232
  require_once WPMTST_INC . 'class-strong-log.php';
233
 
234
  require_once WPMTST_INC . 'class-strong-testimonials-privacy.php';
@@ -278,6 +280,7 @@ final class Strong_Testimonials {
278
  require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-settings-general.php';
279
  require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-settings-form.php';
280
  require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-settings-compat.php';
 
281
  require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-form.php';
282
 
283
  require_once WPMTST_ADMIN . 'about/class-strong-testimonials-welcome.php';
5
  * Description: Collect and display your testimonials or reviews.
6
  * Author: WPChill
7
  * Author URI: https://wpchill.com/
8
+ * Version: 3.0.1
9
  * Text Domain: strong-testimonials
10
  * Domain Path: /languages
11
  * Requires: 4.6 or higher
45
  exit;
46
  }
47
 
48
+ define( 'WPMTST_VERSION', '3.0.1' );
49
  define( 'WPMTST_PLUGIN', plugin_basename( __FILE__ ) ); // strong-testimonials/strong-testimonials.php
50
  define( 'WPMTST', dirname( WPMTST_PLUGIN ) ); // strong-testimonials
51
+ define( 'WPMTST_LOGS', wp_upload_dir()['basedir']. '/st-logs/' );
52
  defined( 'WPMTST_STORE_URL' ) || define( 'WPMTST_STORE_URL', 'https://strongtestimonials.com' );
53
  defined( 'WPMTST_STORE_UPGRADE_URL' ) || define( 'WPMTST_STORE_UPGRADE_URL', 'https://strongtestimonials.com/pricing' );
54
 
230
  * @return void
231
  */
232
  private function includes() {
233
+ require_once WPMTST_INC . '/logs/class-strong-testimonials-logger.php';
234
  require_once WPMTST_INC . 'class-strong-log.php';
235
 
236
  require_once WPMTST_INC . 'class-strong-testimonials-privacy.php';
280
  require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-settings-general.php';
281
  require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-settings-form.php';
282
  require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-settings-compat.php';
283
+ require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-advanced-settings.php';
284
  require_once WPMTST_ADMIN . 'settings/class-strong-testimonials-form.php';
285
 
286
  require_once WPMTST_ADMIN . 'about/class-strong-testimonials-welcome.php';