Advanced Woo Search - Version 1.06

Version Description

  • Cache search results to increase search speed
Download this release

Release Info

Developer Mihail Barinov
Plugin Icon 128x128 Advanced Woo Search
Version 1.06
Comparing to
See all releases

Code changes from version 1.05 to 1.06

advanced-woo-search.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  Plugin Name: Advanced Woo Search
5
  Description: Advance ajax WooCommerce product search.
6
- Version: 1.05
7
  Author: ILLID
8
  Text Domain: aws
9
  */
@@ -13,13 +13,16 @@ if ( ! defined( 'ABSPATH' ) ) {
13
  exit;
14
  }
15
 
16
- define( 'AWS_VERSION', '1.05' );
17
 
18
 
19
  define( 'AWS_DIR', dirname( __FILE__ ) );
20
  define( 'AWS_URL', plugins_url( '', __FILE__ ) );
21
 
22
 
 
 
 
23
  if ( ! class_exists( 'AWS_Main' ) ) :
24
 
25
  /**
@@ -67,9 +70,6 @@ final class AWS_Main {
67
 
68
  add_action( 'wp_enqueue_scripts', array( $this, 'load_scripts' ) );
69
 
70
- add_action( 'wp_ajax_aws_action', array( $this, 'action_callback' ) );
71
- add_action('wp_ajax_nopriv_aws_action', array( $this, 'action_callback' ) );
72
-
73
  add_filter( 'plugin_action_links', array( $this, 'add_action_link' ), 10, 2 );
74
 
75
  //load_plugin_textdomain( 'aws', false, dirname( plugin_basename( __FILE__ ) ). '/languages/' );
@@ -82,8 +82,11 @@ final class AWS_Main {
82
  * Include required core files used in admin and on the frontend.
83
  */
84
  public function includes() {
 
85
  include_once( 'includes/class-aws-admin.php' );
86
  include_once( 'includes/class-aws-table.php' );
 
 
87
  include_once( 'includes/widget.php' );
88
  }
89
 
@@ -92,33 +95,9 @@ final class AWS_Main {
92
  */
93
  public function markup( $args = array() ) {
94
 
95
- $placeholder = $this->get_settings( 'search_field_text' );
96
- $min_chars = $this->get_settings( 'min_chars' );
97
- $show_loader = $this->get_settings( 'show_loader' );
98
-
99
- $params_string = '';
100
-
101
- $params = array(
102
- 'data-url' => admin_url('admin-ajax.php'),
103
- 'data-siteurl' => site_url(),
104
- 'data-show-loader' => $show_loader,
105
- 'data-min-chars' => $min_chars,
106
- );
107
 
108
- foreach( $params as $key => $value ) {
109
- $params_string .= $key . '="' . $value . '"';
110
- }
111
-
112
- $markup = '';
113
- $markup .= '<div class="aws-container" ' . $params_string . '>';
114
- $markup .= '<form class="aws-search-form" action="' . site_url() . '" method="get" role="search" >';
115
- $markup .= '<input type="text" name="s" value="' . get_search_query() . '" class="aws-search-field" placeholder="' . $placeholder . '" autocomplete="off" />';
116
- $markup .= '<input type="hidden" name="post_type" value="product">';
117
- $markup .= '<div class="aws-search-result" style="display: none;"></div>';
118
- $markup .= '</form>';
119
- $markup .= '</div>';
120
-
121
- return apply_filters( 'aws_searchbox_markup', $markup );
122
 
123
  }
124
 
@@ -130,422 +109,6 @@ final class AWS_Main {
130
  wp_enqueue_script( 'aws-script', AWS_URL . '/assets/js/common.js', array('jquery'), AWS_VERSION, true );
131
  }
132
 
133
- /*
134
- * Get array of included to search result posts ids
135
- */
136
- private function get_posts_ids( $sql ) {
137
-
138
- global $wpdb;
139
-
140
- $posts_ids = array();
141
-
142
- $search_results = $wpdb->get_results( $sql );
143
-
144
-
145
- if ( !empty( $search_results ) && !is_wp_error( $search_results ) && is_array( $search_results ) ) {
146
- foreach ( $search_results as $search_result ) {
147
- $post_id = intval( $search_result->ID );
148
- if ( ! in_array( $post_id, $posts_ids ) ) {
149
- $posts_ids[] = $post_id;
150
- }
151
- }
152
- }
153
-
154
- unset( $search_results );
155
-
156
- return $posts_ids;
157
-
158
- }
159
-
160
- /*
161
- * AJAX call action callback
162
- */
163
- public function action_callback() {
164
-
165
- global $wpdb;
166
-
167
- $show_cats = $this->get_settings( 'show_cats' );
168
- $show_tags = $this->get_settings( 'show_tags' );
169
- $results_num = $this->get_settings( 'results_num' );
170
- $search_in = $this->get_settings( 'search_in' );
171
-
172
- $search_in_arr = explode( ',', $this->get_settings( 'search_in' ) );
173
-
174
- // Search in title if all options is disabled
175
- if ( ! $search_in ) {
176
- $search_in_arr = array( 'title' );
177
- }
178
-
179
- $categories_array = array();
180
- $tags_array = array();
181
-
182
- $s = esc_attr( $_POST['keyword'] );
183
- $s = stripslashes( $s );
184
- $s = str_replace( array( "\r", "\n" ), '', $s );
185
-
186
- $this->data['s'] = $s;
187
- $this->data['results_num'] = $results_num;
188
- $this->data['search_terms'] = array();
189
- $this->data['search_in'] = $search_in_arr;
190
-
191
-
192
- $this->data['search_terms'] = array_unique( explode( ' ', $s ) );
193
-
194
- if ( ! count( $this->data['search_terms'] ) > 0 ) {
195
- $this->data['search_terms'] = array( $s );
196
- }
197
-
198
-
199
- $posts_ids = $this->query_index_table();
200
- $products_array = $this->get_products( $posts_ids );
201
-
202
-
203
- if ( $show_cats === 'true' ) {
204
- $categories_array = $this->get_taxonomies( 'product_cat' );
205
- }
206
-
207
- if ( $show_tags === 'true' ) {
208
- $tags_array = $this->get_taxonomies( 'product_tag' );
209
- }
210
-
211
- echo json_encode( array(
212
- 'cats' => $categories_array,
213
- 'tags' => $tags_array,
214
- 'products' => $products_array
215
- ) );
216
-
217
- die;
218
-
219
- }
220
-
221
- /*
222
- * Query in index table
223
- */
224
- private function query_index_table() {
225
-
226
- global $wpdb;
227
-
228
- $table_name = $wpdb->prefix . 'aws_index';
229
-
230
- $search_in_arr = $this->data['search_in'];
231
- $results_num = $this->data['results_num'];
232
-
233
- $query = array();
234
-
235
- $query['search'] = '';
236
- $query['source'] = '';
237
- $query['relevance'] = '';
238
-
239
- $search_array = array();
240
- $source_array = array();
241
- $relevance_array = array();
242
- $new_relevance_array = array();
243
-
244
-
245
- foreach ( $this->data['search_terms'] as $search_term ) {
246
-
247
- $like = '%' . $wpdb->esc_like( $search_term ) . '%';
248
-
249
- $search_array[] = $wpdb->prepare( '( term LIKE %s )', $like );
250
-
251
- foreach ( $search_in_arr as $search_in_term ) {
252
-
253
- switch ( $search_in_term ) {
254
-
255
- case 'title':
256
- $relevance_array['title'][] = $wpdb->prepare( "( case when ( term_source = 'title' AND term LIKE %s ) then 10 else 0 end )", $like );
257
- break;
258
-
259
- case 'content':
260
- $relevance_array['content'][] = $wpdb->prepare( "( case when ( term_source = 'content' AND term LIKE %s ) then 7 else 0 end )", $like );
261
- break;
262
-
263
- case 'excerpt':
264
- $relevance_array['content'][] = $wpdb->prepare( "( case when ( term_source = 'excerpt' AND term LIKE %s ) then 7 else 0 end )", $like );
265
- break;
266
-
267
- case 'category':
268
- $relevance_array['category'][] = $wpdb->prepare( "( case when ( term_source = 'category' AND term LIKE %s ) then 5 else 0 end )", $like );
269
- break;
270
-
271
- case 'tag':
272
- $relevance_array['tag'][] = $wpdb->prepare( "( case when ( term_source = 'tag' AND term LIKE %s ) then 5 else 0 end )", $like );
273
- break;
274
-
275
- }
276
-
277
- }
278
-
279
- }
280
-
281
- // Sort 'relevance' queries in the array by search priority
282
- foreach ( $search_in_arr as $search_in_item ) {
283
- if ( isset( $relevance_array[$search_in_item] ) ) {
284
- $new_relevance_array[$search_in_item] = implode( ' + ', $relevance_array[$search_in_item] );
285
- }
286
- }
287
-
288
- foreach ( $search_in_arr as $search_in_term ) {
289
- $source_array[] = "term_source = '{$search_in_term}'";
290
- }
291
-
292
- $query['relevance'] .= sprintf( ' (SUM( %s )) ', implode( ' + ', $new_relevance_array ) );
293
- $query['search'] .= sprintf( ' AND ( %s )', implode( ' OR ', $search_array ) );
294
- $query['source'] .= sprintf( ' AND ( %s )', implode( ' OR ', $source_array ) );
295
-
296
-
297
- $sql = "SELECT
298
- distinct ID,
299
- {$query['relevance']} as relevance
300
- FROM
301
- {$table_name}
302
- WHERE
303
- type = 'product'
304
- {$query['source']}
305
- {$query['search']}
306
- GROUP BY ID
307
- ORDER BY
308
- relevance DESC
309
- LIMIT 0, {$results_num}
310
- ";
311
-
312
- $posts_ids = $this->get_posts_ids( $sql );
313
-
314
- return $posts_ids;
315
-
316
- }
317
-
318
- /*
319
- * Get products info
320
- */
321
- private function get_products( $posts_ids ) {
322
-
323
- $products_array = array();
324
-
325
- if ( count( $posts_ids ) > 0 ) {
326
-
327
- $show_excerpt = $this->get_settings( 'show_excerpt' );
328
- $excerpt_source = $this->get_settings( 'desc_source' );
329
- $excerpt_length = $this->get_settings( 'excerpt_length' );
330
- $mark_search_words = $this->get_settings( 'mark_words' );
331
- $show_price = $this->get_settings( 'show_price' );
332
- $show_sale = $this->get_settings( 'show_sale' );
333
- $show_image = $this->get_settings( 'show_image' );
334
- $show_sku = $this->get_settings( 'show_sku' );
335
-
336
- foreach ( $posts_ids as $post_id ) {
337
-
338
- $product = new WC_product( $post_id );
339
-
340
- $post_data = $product->get_post_data();
341
-
342
- $title = $product->get_title();
343
-
344
- $excerpt = '';
345
- $price = '';
346
- $on_sale = '';
347
- $image = '';
348
- $sku = '';
349
-
350
- if ( $show_excerpt === 'true' ) {
351
- $excerpt = ( $excerpt_source === 'excerpt' && $post_data->post_excerpt ) ? $post_data->post_excerpt : $post_data->post_content;
352
- $excerpt = wp_trim_words( $excerpt, $excerpt_length, '...' );
353
- }
354
-
355
- if ( $mark_search_words === 'true' ) {
356
-
357
- $marked_content = $this->mark_search_words( $title, $excerpt );
358
-
359
- $title = $marked_content['title'];
360
- $excerpt = $marked_content['excerpt'];
361
-
362
- }
363
-
364
- if ( $show_price === 'true' ) {
365
- $price = $product->get_price_html();
366
- }
367
-
368
- if ( $show_sale === 'true' ) {
369
- $on_sale = $product->is_on_sale();
370
- }
371
-
372
- if ( $show_image === 'true' ) {
373
- $image_id = $product->get_image_id();
374
- $image_attributes = wp_get_attachment_image_src( $image_id );
375
- $image = $image_attributes[0];
376
- }
377
-
378
- if ( $show_sku === 'true' ) {
379
- $sku = $product->get_sku();
380
- }
381
-
382
- $categories = $product->get_categories( ',' );
383
-
384
- $tags = $product->get_tags( ',' );
385
-
386
- $new_result = array(
387
- 'title' => $title,
388
- 'excerpt' => $excerpt,
389
- 'link' => get_permalink( $post_id ),
390
- 'image' => $image,
391
- 'price' => $price,
392
- 'categories' => $categories,
393
- 'tags' => $tags,
394
- 'on_sale' => $on_sale,
395
- 'sku' => $sku
396
- );
397
-
398
- $products_array[] = $new_result;
399
- }
400
-
401
- }
402
-
403
- return $products_array;
404
-
405
- }
406
-
407
- /*
408
- * Mark search words
409
- */
410
- private function mark_search_words( $title, $excerpt ) {
411
-
412
- $show_excerpt = $this->get_settings( 'show_excerpt' );
413
-
414
- $pattern = array();
415
-
416
- foreach( $this->data['search_terms'] as $search_in ) {
417
- $pattern[] = '(' . $search_in . ')+';
418
- }
419
-
420
- usort( $pattern, array( $this, 'sort_by_length' ) );
421
- $pattern = implode( '|', $pattern );
422
- $pattern = sprintf( '/%s/i', $pattern );
423
-
424
- if ( in_array( 'title', $this->data['search_in'] ) ) {
425
- $title = preg_replace($pattern, '<strong>${0}</strong>', $title);
426
- }
427
-
428
- if ( $show_excerpt === 'true' && in_array( 'content', $this->data['search_in'] ) ) {
429
- $excerpt = preg_replace( $pattern, '<strong>${0}</strong>', $excerpt );
430
- }
431
-
432
- return array(
433
- 'title' => $title,
434
- 'excerpt' => $excerpt
435
- );
436
-
437
- }
438
-
439
- /*
440
- * Sort array by its values length
441
- */
442
- private function sort_by_length( $a, $b ) {
443
- return strlen( $b ) - strlen( $a );
444
- }
445
-
446
- /*
447
- * Check if the terms are suitable for searching
448
- */
449
- private function parse_search_terms( $terms ) {
450
-
451
- $strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
452
- $checked = array();
453
-
454
- $stopwords = $this->get_search_stopwords();
455
-
456
- foreach ( $terms as $term ) {
457
-
458
- // Avoid single A-Z.
459
- if ( ! $term || ( 1 === strlen( $term ) && preg_match( '/^[a-z]$/i', $term ) ) )
460
- continue;
461
-
462
- if ( in_array( call_user_func( $strtolower, $term ), $stopwords, true ) )
463
- continue;
464
-
465
- $checked[] = $term;
466
- }
467
-
468
- return $checked;
469
-
470
- }
471
-
472
- /*
473
- * Get array of stopwords
474
- */
475
- private function get_search_stopwords() {
476
-
477
- $stopwords = array( 'about','an','are','as','at','be','by','com','for','from','how','in','is','it','of','on','or','that','the','this','to','was','what','when','where','who','will','with','www' );
478
-
479
- return $stopwords;
480
-
481
- }
482
-
483
- /*
484
- * Query product taxonomies
485
- */
486
- private function get_taxonomies( $taxonomy ) {
487
-
488
- global $wpdb;
489
-
490
- $result_array = array();
491
- $search_array = array();
492
- $excludes = '';
493
- $search_query = '';
494
-
495
- foreach ( $this->data['search_terms'] as $search_term ) {
496
- $like = '%' . $wpdb->esc_like($search_term) . '%';
497
- $search_array[] = $wpdb->prepare('( name LIKE %s )', $like);
498
- }
499
-
500
- $search_query .= sprintf( ' AND ( %s )', implode( ' OR ', $search_array ) );
501
-
502
-
503
- $sql = "
504
- SELECT
505
- distinct($wpdb->terms.name),
506
- $wpdb->terms.term_id,
507
- $wpdb->term_taxonomy.taxonomy,
508
- $wpdb->term_taxonomy.count
509
- FROM
510
- $wpdb->terms
511
- , $wpdb->term_taxonomy
512
- WHERE 1 = 1
513
- {$search_query}
514
- AND $wpdb->term_taxonomy.taxonomy = '{$taxonomy}'
515
- AND $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
516
- $excludes
517
- LIMIT 0, 10";
518
-
519
- $search_results = $wpdb->get_results( $sql );
520
-
521
- if ( ! empty( $search_results ) && !is_wp_error( $search_results ) ) {
522
-
523
- foreach ( $search_results as $result ) {
524
-
525
- $term = get_term( $result->term_id, $result->taxonomy );
526
-
527
- if ( $term != null && !is_wp_error( $term ) ) {
528
- $term_link = get_term_link( $term );
529
- } else {
530
- $term_link = '';
531
- }
532
-
533
- $new_result = array(
534
- 'name' => $result->name,
535
- 'count' => $result->count,
536
- 'link' => $term_link
537
- );
538
-
539
- $result_array[] = $new_result;
540
-
541
- }
542
-
543
- }
544
-
545
- return $result_array;
546
-
547
- }
548
-
549
  /*
550
  * Get plugin settings
551
  */
3
  /*
4
  Plugin Name: Advanced Woo Search
5
  Description: Advance ajax WooCommerce product search.
6
+ Version: 1.06
7
  Author: ILLID
8
  Text Domain: aws
9
  */
13
  exit;
14
  }
15
 
16
+ define( 'AWS_VERSION', '1.06' );
17
 
18
 
19
  define( 'AWS_DIR', dirname( __FILE__ ) );
20
  define( 'AWS_URL', plugins_url( '', __FILE__ ) );
21
 
22
 
23
+ define( 'AWS_INDEX_TABLE_NAME', 'aws_index' );
24
+
25
+
26
  if ( ! class_exists( 'AWS_Main' ) ) :
27
 
28
  /**
70
 
71
  add_action( 'wp_enqueue_scripts', array( $this, 'load_scripts' ) );
72
 
 
 
 
73
  add_filter( 'plugin_action_links', array( $this, 'add_action_link' ), 10, 2 );
74
 
75
  //load_plugin_textdomain( 'aws', false, dirname( plugin_basename( __FILE__ ) ). '/languages/' );
82
  * Include required core files used in admin and on the frontend.
83
  */
84
  public function includes() {
85
+ include_once( 'includes/class-aws-helpers.php' );
86
  include_once( 'includes/class-aws-admin.php' );
87
  include_once( 'includes/class-aws-table.php' );
88
+ include_once( 'includes/class-aws-markup.php' );
89
+ include_once( 'includes/class-aws-search.php' );
90
  include_once( 'includes/widget.php' );
91
  }
92
 
95
  */
96
  public function markup( $args = array() ) {
97
 
98
+ $markup = new AWS_Markup();
 
 
 
 
 
 
 
 
 
 
 
99
 
100
+ return $markup->markup();
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  }
103
 
109
  wp_enqueue_script( 'aws-script', AWS_URL . '/assets/js/common.js', array('jquery'), AWS_VERSION, true );
110
  }
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  /*
113
  * Get plugin settings
114
  */
assets/js/admin.js CHANGED
@@ -26,5 +26,29 @@ jQuery(document).ready(function ($) {
26
 
27
  });
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  });
26
 
27
  });
28
 
29
+ // Clear cache
30
+ $('#aws-clear-cache .button').on( 'click', function(e) {
31
+
32
+ e.preventDefault();
33
+
34
+ var $clearCacheBlock = $(this).closest('#aws-clear-cache');
35
+
36
+ $clearCacheBlock.addClass('loading');
37
+
38
+ $.ajax({
39
+ type: 'POST',
40
+ url: aws_vars.ajaxurl,
41
+ data: {
42
+ action: 'aws-clear-cache'
43
+ },
44
+ dataType: "json",
45
+ success: function (data) {
46
+ alert('Cache cleared!');
47
+ $clearCacheBlock.removeClass('loading');
48
+ }
49
+ });
50
+
51
+ });
52
+
53
 
54
  });
includes/class-aws-admin.php CHANGED
@@ -98,6 +98,9 @@ class AWS_Admin {
98
  }
99
 
100
  update_option( 'aws_settings', $update_settings );
 
 
 
101
  }
102
 
103
  echo '<div class="wrap">';
@@ -344,14 +347,26 @@ class AWS_Admin {
344
 
345
  echo '<tr>';
346
 
347
- echo '<th>Reindex table</th>';
348
- echo '<td>';
349
- echo '<div id="aws-reindex"><input class="button" type="button" value="Reindex table"><span class="loader"></span></div><br><br>';
350
- echo '<span class="description">Update all data in plugins index table. Index table - table with products data where plugin is searching all typed terms.<br>Use this button if you think that plugin not shows last actual data in its search results.<br><strong>CAUTION:</strong> this can take large amount of time.</span>';
351
- echo '</td>';
 
 
 
352
 
353
  echo '<tr>';
354
 
 
 
 
 
 
 
 
 
 
355
  }
356
 
357
  /*
98
  }
99
 
100
  update_option( 'aws_settings', $update_settings );
101
+
102
+ do_action( 'aws_settings_saved' );
103
+
104
  }
105
 
106
  echo '<div class="wrap">';
347
 
348
  echo '<tr>';
349
 
350
+ echo '<th>Reindex table</th>';
351
+ echo '<td>';
352
+ echo '<div id="aws-reindex"><input class="button" type="button" value="Reindex table"><span class="loader"></span></div><br><br>';
353
+ echo '<span class="description">Update all data in plugins index table. Index table - table with products data where plugin is searching all typed terms.<br>Use this button if you think that plugin not shows last actual data in its search results.<br><strong>CAUTION:</strong> this can take large amount of time.</span>';
354
+ echo '</td>';
355
+
356
+ echo '<tr>';
357
+
358
 
359
  echo '<tr>';
360
 
361
+ echo '<th>Clear cache</th>';
362
+ echo '<td>';
363
+ echo '<div id="aws-clear-cache"><input class="button" type="button" value="Clear cache"><span class="loader"></span></div><br>';
364
+ echo '<span class="description">Clear cache for all search results.</span>';
365
+ echo '</td>';
366
+
367
+ echo '<tr>';
368
+
369
+
370
  }
371
 
372
  /*
includes/class-aws-helpers.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+
8
+ if ( ! class_exists( 'AWS_Helpers' ) ) :
9
+
10
+ /**
11
+ * Class for plugin help methods
12
+ */
13
+ class AWS_Helpers {
14
+
15
+ /*
16
+ * Removes scripts, styles, html tags
17
+ */
18
+ static public function html2txt( $str ) {
19
+ $search = array(
20
+ '@<script[^>]*?>.*?</script>@si',
21
+ '@<[\/\!]*?[^<>]*?>@si',
22
+ '@<style[^>]*?>.*?</style>@siU',
23
+ '@<![\s\S]*?--[ \t\n\r]*>@'
24
+ );
25
+ $str = preg_replace( $search, '', $str );
26
+
27
+ $str = esc_attr( $str );
28
+ $str = stripslashes( $str );
29
+ $str = str_replace( array( "\r", "\n" ), ' ', $str );
30
+
31
+ $str = str_replace( array(
32
+ "·",
33
+ "…",
34
+ "€",
35
+ "&shy;"
36
+ ), "", $str );
37
+
38
+ return $str;
39
+ }
40
+
41
+ }
42
+
43
+ endif;
includes/class-aws-markup.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+ if ( ! class_exists( 'AWS_Markup' ) ) :
8
+
9
+ /**
10
+ * Class for plugin search action
11
+ */
12
+ class AWS_Markup {
13
+
14
+ /*
15
+ * Generate search box markup
16
+ */
17
+ public function markup() {
18
+
19
+ global $wpdb;
20
+
21
+ $table_name = $wpdb->prefix . AWS_INDEX_TABLE_NAME;
22
+
23
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" ) != $table_name ) {
24
+ echo 'Please go to <a href="' . admin_url( 'admin.php?page=aws-options' ) . '">plugins settings page</a> and click on "Reindex table" button.';
25
+ return;
26
+ }
27
+
28
+ $placeholder = $this->get_settings( 'search_field_text' );
29
+ $min_chars = $this->get_settings( 'min_chars' );
30
+ $show_loader = $this->get_settings( 'show_loader' );
31
+
32
+ $params_string = '';
33
+
34
+ $params = array(
35
+ 'data-url' => admin_url('admin-ajax.php'),
36
+ 'data-siteurl' => site_url(),
37
+ 'data-show-loader' => $show_loader,
38
+ 'data-min-chars' => $min_chars,
39
+ );
40
+
41
+ foreach( $params as $key => $value ) {
42
+ $params_string .= $key . '="' . $value . '"';
43
+ }
44
+
45
+ $markup = '';
46
+ $markup .= '<div class="aws-container" ' . $params_string . '>';
47
+ $markup .= '<form class="aws-search-form" action="' . site_url() . '" method="get" role="search" >';
48
+ $markup .= '<input type="text" name="s" value="' . get_search_query() . '" class="aws-search-field" placeholder="' . $placeholder . '" autocomplete="off" />';
49
+ $markup .= '<input type="hidden" name="post_type" value="product">';
50
+ $markup .= '<div class="aws-search-result" style="display: none;"></div>';
51
+ $markup .= '</form>';
52
+ $markup .= '</div>';
53
+
54
+ return apply_filters( 'aws_searchbox_markup', $markup );
55
+
56
+ }
57
+
58
+ /*
59
+ * Get plugin settings
60
+ */
61
+ private function get_settings( $name ) {
62
+ $plugin_options = get_option( 'aws_settings' );
63
+ return $plugin_options[ $name ];
64
+ }
65
+
66
+ }
67
+
68
+ endif;
includes/class-aws-search.php ADDED
@@ -0,0 +1,518 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+ if ( ! class_exists( 'AWS_Search' ) ) :
8
+
9
+ /**
10
+ * Class for plugin search
11
+ */
12
+ class AWS_Search {
13
+
14
+ /**
15
+ * @var AWS_Search Array of all plugin data $data
16
+ */
17
+ private $data = array();
18
+
19
+ /**
20
+ * Constructor
21
+ */
22
+ public function __construct() {
23
+
24
+ $this->data['settings'] = get_option( 'aws_settings' );
25
+
26
+ add_action( 'wp_ajax_aws_action', array( $this, 'action_callback' ) );
27
+ add_action( 'wp_ajax_nopriv_aws_action', array( $this, 'action_callback' ) );
28
+
29
+ }
30
+
31
+ /*
32
+ * AJAX call action callback
33
+ */
34
+ public function action_callback() {
35
+
36
+ global $wpdb;
37
+
38
+ $cache = $this->get_settings( 'cache' );
39
+
40
+ $s = esc_attr( $_POST['keyword'] );
41
+ $s = stripslashes( $s );
42
+ $s = str_replace( array( "\r", "\n" ), '', $s );
43
+
44
+
45
+ if ( $cache === 'true' ) {
46
+
47
+ $cache_option_name = 'aws_search_term_' . $s;
48
+
49
+ // Check if value was already cached
50
+ if ($cached_value = get_option($cache_option_name)) {
51
+ $cached_value['cache'] = 'cached';
52
+ echo json_encode($cached_value);
53
+ die;
54
+ }
55
+
56
+ }
57
+
58
+
59
+ $show_cats = $this->get_settings( 'show_cats' );
60
+ $show_tags = $this->get_settings( 'show_tags' );
61
+ $results_num = $this->get_settings( 'results_num' );
62
+ $search_in = $this->get_settings( 'search_in' );
63
+
64
+ $search_in_arr = explode( ',', $this->get_settings( 'search_in' ) );
65
+
66
+ // Search in title if all options is disabled
67
+ if ( ! $search_in ) {
68
+ $search_in_arr = array( 'title' );
69
+ }
70
+
71
+ $categories_array = array();
72
+ $tags_array = array();
73
+
74
+
75
+ $this->data['s'] = $s;
76
+ $this->data['results_num'] = $results_num;
77
+ $this->data['search_terms'] = array();
78
+ $this->data['search_terms'] = array_unique( explode( ' ', $s ) );
79
+ $this->data['search_in'] = $search_in_arr;
80
+
81
+
82
+ $posts_ids = $this->query_index_table();
83
+ $products_array = $this->get_products( $posts_ids );
84
+
85
+
86
+ if ( $show_cats === 'true' ) {
87
+ $categories_array = $this->get_taxonomies( 'product_cat' );
88
+ }
89
+
90
+ if ( $show_tags === 'true' ) {
91
+ $tags_array = $this->get_taxonomies( 'product_tag' );
92
+ }
93
+
94
+ $result_array = array(
95
+ 'cats' => $categories_array,
96
+ 'tags' => $tags_array,
97
+ 'products' => $products_array
98
+ );
99
+
100
+
101
+ if ( $cache === 'true' ) {
102
+ update_option( $cache_option_name, $result_array );
103
+ }
104
+
105
+
106
+ echo json_encode( $result_array );
107
+
108
+ die;
109
+
110
+ }
111
+
112
+ /*
113
+ * Query in index table
114
+ */
115
+ private function query_index_table() {
116
+
117
+ global $wpdb;
118
+
119
+ $table_name = $wpdb->prefix . AWS_INDEX_TABLE_NAME;
120
+
121
+ $search_in_arr = $this->data['search_in'];
122
+ $results_num = $this->data['results_num'];
123
+
124
+ $query = array();
125
+
126
+ $query['search'] = '';
127
+ $query['source'] = '';
128
+ $query['relevance'] = '';
129
+
130
+ $search_array = array();
131
+ $source_array = array();
132
+ $relevance_array = array();
133
+ $new_relevance_array = array();
134
+
135
+
136
+ foreach ( $this->data['search_terms'] as $search_term ) {
137
+
138
+ $search_term_len = strlen( $search_term );
139
+
140
+ $relevance_title = 200 + 20 * $search_term_len;
141
+ $relevance_content = 35 + 4 * $search_term_len;
142
+ $relevance_title_like = 40 + 2 * $search_term_len;
143
+ $relevance_content_like = 35 + 1 * $search_term_len;
144
+
145
+
146
+ $like = '%' . $wpdb->esc_like( $search_term ) . '%';
147
+
148
+ if ( $search_term_len > 1 ) {
149
+ $search_array[] = $wpdb->prepare( '( term LIKE %s )', $like );
150
+ } else {
151
+ $search_array[] = $wpdb->prepare( '( term = "%s" )', $search_term );
152
+ }
153
+
154
+ foreach ( $search_in_arr as $search_in_term ) {
155
+
156
+ switch ( $search_in_term ) {
157
+
158
+ case 'title':
159
+ $relevance_array['title'][] = $wpdb->prepare( "( case when ( term_source = 'title' AND term = '%s' ) then {$relevance_title} * count else 0 end )", $search_term );
160
+ $relevance_array['title'][] = $wpdb->prepare( "( case when ( term_source = 'title' AND term LIKE %s ) then {$relevance_title_like} * count else 0 end )", $like );
161
+ break;
162
+
163
+ case 'content':
164
+ $relevance_array['content'][] = $wpdb->prepare( "( case when ( term_source = 'content' AND term = '%s' ) then {$relevance_content} * count else 0 end )", $search_term );
165
+ $relevance_array['content'][] = $wpdb->prepare( "( case when ( term_source = 'content' AND term LIKE %s ) then {$relevance_content_like} * count else 0 end )", $like );
166
+ break;
167
+
168
+ case 'excerpt':
169
+ $relevance_array['content'][] = $wpdb->prepare( "( case when ( term_source = 'excerpt' AND term = '%s' ) then {$relevance_content} * count else 0 end )", $search_term );
170
+ $relevance_array['content'][] = $wpdb->prepare( "( case when ( term_source = 'excerpt' AND term LIKE %s ) then {$relevance_content_like} * count else 0 end )", $like );
171
+ break;
172
+
173
+ case 'category':
174
+ $relevance_array['category'][] = $wpdb->prepare( "( case when ( term_source = 'category' AND term = '%s' ) then 35 else 0 end )", $search_term );
175
+ $relevance_array['category'][] = $wpdb->prepare( "( case when ( term_source = 'category' AND term LIKE %s ) then 5 else 0 end )", $like );
176
+ break;
177
+
178
+ case 'tag':
179
+ $relevance_array['tag'][] = $wpdb->prepare( "( case when ( term_source = 'tag' AND term = '%s' ) then 35 else 0 end )", $search_term );
180
+ $relevance_array['tag'][] = $wpdb->prepare( "( case when ( term_source = 'tag' AND term LIKE %s ) then 5 else 0 end )", $like );
181
+ break;
182
+
183
+ }
184
+
185
+ }
186
+
187
+ }
188
+
189
+ // Sort 'relevance' queries in the array by search priority
190
+ foreach ( $search_in_arr as $search_in_item ) {
191
+ if ( isset( $relevance_array[$search_in_item] ) ) {
192
+ $new_relevance_array[$search_in_item] = implode( ' + ', $relevance_array[$search_in_item] );
193
+ }
194
+ }
195
+
196
+ foreach ( $search_in_arr as $search_in_term ) {
197
+ $source_array[] = "term_source = '{$search_in_term}'";
198
+ }
199
+
200
+ $query['relevance'] .= sprintf( ' (SUM( %s )) ', implode( ' + ', $new_relevance_array ) );
201
+ $query['search'] .= sprintf( ' AND ( %s )', implode( ' OR ', $search_array ) );
202
+ $query['source'] .= sprintf( ' AND ( %s )', implode( ' OR ', $source_array ) );
203
+
204
+
205
+ $sql = "SELECT
206
+ distinct ID,
207
+ {$query['relevance']} as relevance
208
+ FROM
209
+ {$table_name}
210
+ WHERE
211
+ type = 'product'
212
+ {$query['source']}
213
+ {$query['search']}
214
+ GROUP BY ID
215
+ ORDER BY
216
+ relevance DESC
217
+ LIMIT 0, {$results_num}
218
+ ";
219
+
220
+ $posts_ids = $this->get_posts_ids( $sql );
221
+
222
+ return $posts_ids;
223
+
224
+ }
225
+
226
+ /*
227
+ * Get array of included to search result posts ids
228
+ */
229
+ private function get_posts_ids( $sql ) {
230
+
231
+ global $wpdb;
232
+
233
+ $posts_ids = array();
234
+
235
+ $search_results = $wpdb->get_results( $sql );
236
+
237
+
238
+ if ( !empty( $search_results ) && !is_wp_error( $search_results ) && is_array( $search_results ) ) {
239
+ foreach ( $search_results as $search_result ) {
240
+ $post_id = intval( $search_result->ID );
241
+ if ( ! in_array( $post_id, $posts_ids ) ) {
242
+ $posts_ids[] = $post_id;
243
+ }
244
+ }
245
+ }
246
+
247
+ unset( $search_results );
248
+
249
+ return $posts_ids;
250
+
251
+ }
252
+
253
+ /*
254
+ * Get products info
255
+ */
256
+ private function get_products( $posts_ids ) {
257
+
258
+ $products_array = array();
259
+
260
+ if ( count( $posts_ids ) > 0 ) {
261
+
262
+ $show_excerpt = $this->get_settings( 'show_excerpt' );
263
+ $excerpt_source = $this->get_settings( 'desc_source' );
264
+ $excerpt_length = $this->get_settings( 'excerpt_length' );
265
+ $mark_search_words = $this->get_settings( 'mark_words' );
266
+ $show_price = $this->get_settings( 'show_price' );
267
+ $show_sale = $this->get_settings( 'show_sale' );
268
+ $show_image = $this->get_settings( 'show_image' );
269
+ $show_sku = $this->get_settings( 'show_sku' );
270
+
271
+ foreach ( $posts_ids as $post_id ) {
272
+
273
+ $product = new WC_product( $post_id );
274
+
275
+ $post_data = $product->get_post_data();
276
+
277
+ $title = $product->get_title();
278
+ $title = AWS_Helpers::html2txt( $title );
279
+
280
+ $excerpt = '';
281
+ $price = '';
282
+ $on_sale = '';
283
+ $image = '';
284
+ $sku = '';
285
+
286
+ if ( $show_excerpt === 'true' ) {
287
+ $excerpt = ( $excerpt_source === 'excerpt' && $post_data->post_excerpt ) ? $post_data->post_excerpt : $post_data->post_content;
288
+ $excerpt = AWS_Helpers::html2txt( $excerpt );
289
+ $excerpt = str_replace('"', "'", $excerpt);
290
+ }
291
+
292
+ if ( $mark_search_words === 'true' ) {
293
+
294
+ $marked_content = $this->mark_search_words( $title, $excerpt );
295
+
296
+ $title = $marked_content['title'];
297
+ $excerpt = $marked_content['content'];
298
+
299
+ } else {
300
+ $excerpt = wp_trim_words( $excerpt, $excerpt_length, '...' );
301
+ }
302
+
303
+ if ( $show_price === 'true' ) {
304
+ $price = $product->get_price_html();
305
+ }
306
+
307
+ if ( $show_sale === 'true' ) {
308
+ $on_sale = $product->is_on_sale();
309
+ }
310
+
311
+ if ( $show_image === 'true' ) {
312
+ $image_id = $product->get_image_id();
313
+ $image_attributes = wp_get_attachment_image_src( $image_id );
314
+ $image = $image_attributes[0];
315
+ }
316
+
317
+ if ( $show_sku === 'true' ) {
318
+ $sku = $product->get_sku();
319
+ }
320
+
321
+ $categories = $product->get_categories( ',' );
322
+
323
+ $tags = $product->get_tags( ',' );
324
+
325
+ $new_result = array(
326
+ 'title' => $title,
327
+ 'excerpt' => $excerpt,
328
+ 'link' => get_permalink( $post_id ),
329
+ 'image' => $image,
330
+ 'price' => $price,
331
+ 'categories' => $categories,
332
+ 'tags' => $tags,
333
+ 'on_sale' => $on_sale,
334
+ 'sku' => $sku
335
+ );
336
+
337
+ $products_array[] = $new_result;
338
+ }
339
+
340
+ }
341
+
342
+ return $products_array;
343
+
344
+ }
345
+
346
+ /*
347
+ * Mark search words
348
+ */
349
+ private function mark_search_words( $title, $content ) {
350
+
351
+ $pattern = array();
352
+ $exact_pattern = array();
353
+ $exact_words = array();
354
+ $words = array();
355
+
356
+ foreach( $this->data['search_terms'] as $search_in ) {
357
+
358
+ $exact_words[] = '\b' . $search_in . '\b';
359
+ $exact_pattern[] = '(\b' . $search_in . '\b)+';
360
+
361
+ if ( strlen( $search_in ) > 1 ) {
362
+ $pattern[] = '(' . $search_in . ')+';
363
+ $words[] = $search_in;
364
+ } else {
365
+ $pattern[] = '\b[' . $search_in . ']{1}\b';
366
+ $words[] = '\b' . $search_in . '\b';
367
+ }
368
+
369
+ }
370
+
371
+ usort( $exact_words, array( $this, 'sort_by_length' ) );
372
+ $exact_words = implode( '|', $exact_words );
373
+
374
+ usort( $words, array( $this, 'sort_by_length' ) );
375
+ $words = implode( '|', $words );
376
+
377
+ usort( $exact_pattern, array( $this, 'sort_by_length' ) );
378
+ $exact_pattern = implode( '|', $exact_pattern );
379
+ $exact_pattern = sprintf( '/%s/i', $exact_pattern );
380
+
381
+ usort( $pattern, array( $this, 'sort_by_length' ) );
382
+ $pattern = implode( '|', $pattern );
383
+ $pattern = sprintf( '/%s/i', $pattern );
384
+
385
+
386
+ preg_match( '/([^.?!]*?)(' . $exact_words . '){1}(.*?[.!?])/i', $content, $matches );
387
+
388
+ if ( ! $matches[0] ) {
389
+ preg_match( '/([^.?!]*?)(' . $words . '){1}(.*?[.!?])/i', $content, $matches );
390
+ }
391
+
392
+ if ( ! $matches[0] ) {
393
+ preg_match( '/([^.?!]*?)(.*?)(.*?[.!?])/i', $content, $matches );
394
+ }
395
+
396
+ $content = $matches[0];
397
+
398
+
399
+ // Trim to long content
400
+ if ( str_word_count( strip_tags( $content ) ) > 34 ) {
401
+
402
+ if ( str_word_count( strip_tags( $matches[3] ) ) > 34 ) {
403
+ $matches[3] = wp_trim_words( $matches[3], 30, '...' );
404
+ }
405
+
406
+ $content = '...' . $matches[2] . $matches[3];
407
+
408
+ }
409
+
410
+
411
+ $title_has_exact = preg_match( '/(' . $exact_words . '){1}/i', $title );
412
+ $content_has_exact = preg_match( '/(' . $exact_words . '){1}/i', $content );
413
+
414
+
415
+ if ( $title_has_exact === 1 || $content_has_exact === 1 ) {
416
+ $title = preg_replace($exact_pattern, '<strong>${0}</strong>', $title );
417
+ $content = preg_replace($exact_pattern, '<strong>${0}</strong>', $content );
418
+ } else {
419
+ $title = preg_replace($pattern, '<strong>${0}</strong>', $title );
420
+ $content = preg_replace( $pattern, '<strong>${0}</strong>', $content );
421
+ }
422
+
423
+
424
+ return array(
425
+ 'title' => $title,
426
+ 'content' => $content
427
+ );
428
+
429
+ }
430
+
431
+ /*
432
+ * Sort array by its values length
433
+ */
434
+ private function sort_by_length( $a, $b ) {
435
+ return strlen( $b ) - strlen( $a );
436
+ }
437
+
438
+ /*
439
+ * Query product taxonomies
440
+ */
441
+ private function get_taxonomies( $taxonomy ) {
442
+
443
+ global $wpdb;
444
+
445
+ $result_array = array();
446
+ $search_array = array();
447
+ $excludes = '';
448
+ $search_query = '';
449
+
450
+ foreach ( $this->data['search_terms'] as $search_term ) {
451
+ $like = '%' . $wpdb->esc_like($search_term) . '%';
452
+ $search_array[] = $wpdb->prepare('( name LIKE %s )', $like);
453
+ }
454
+
455
+ $search_query .= sprintf( ' AND ( %s )', implode( ' OR ', $search_array ) );
456
+
457
+
458
+ $sql = "
459
+ SELECT
460
+ distinct($wpdb->terms.name),
461
+ $wpdb->terms.term_id,
462
+ $wpdb->term_taxonomy.taxonomy,
463
+ $wpdb->term_taxonomy.count
464
+ FROM
465
+ $wpdb->terms
466
+ , $wpdb->term_taxonomy
467
+ WHERE 1 = 1
468
+ {$search_query}
469
+ AND $wpdb->term_taxonomy.taxonomy = '{$taxonomy}'
470
+ AND $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
471
+ $excludes
472
+ LIMIT 0, 10";
473
+
474
+ $search_results = $wpdb->get_results( $sql );
475
+
476
+ if ( ! empty( $search_results ) && !is_wp_error( $search_results ) ) {
477
+
478
+ foreach ( $search_results as $result ) {
479
+
480
+ $term = get_term( $result->term_id, $result->taxonomy );
481
+
482
+ if ( $term != null && !is_wp_error( $term ) ) {
483
+ $term_link = get_term_link( $term );
484
+ } else {
485
+ $term_link = '';
486
+ }
487
+
488
+ $new_result = array(
489
+ 'name' => $result->name,
490
+ 'count' => $result->count,
491
+ 'link' => $term_link
492
+ );
493
+
494
+ $result_array[] = $new_result;
495
+
496
+ }
497
+
498
+ }
499
+
500
+ return $result_array;
501
+
502
+ }
503
+
504
+ /*
505
+ * Get plugin settings
506
+ */
507
+ public function get_settings( $name ) {
508
+ $plugin_options = $this->data['settings'];
509
+ return $plugin_options[ $name ];
510
+ }
511
+
512
+ }
513
+
514
+
515
+ endif;
516
+
517
+
518
+ new AWS_Search();
includes/class-aws-table.php CHANGED
@@ -23,15 +23,25 @@ if ( ! class_exists( 'AWS_Table' ) ) :
23
 
24
  global $wpdb;
25
 
26
- $this->table_name = $wpdb->prefix . 'aws_index';
27
 
28
- add_action( 'wp_loaded', array( $this, 'check_table' ) );
29
 
30
  add_action( 'save_post', array( $this, 'update_table' ), 10, 3 );
31
 
 
 
 
 
 
 
 
32
  add_action( 'wp_ajax_aws-reindex', array( $this, 'reindex_table' ) );
33
  add_action( 'wp_ajax_nopriv_aws-reindex', array( $this, 'reindex_table' ) );
34
 
 
 
 
35
  }
36
 
37
  /*
@@ -45,6 +55,8 @@ if ( ! class_exists( 'AWS_Table' ) ) :
45
 
46
  $this->check_table();
47
 
 
 
48
  }
49
 
50
  /*
@@ -170,6 +182,36 @@ if ( ! class_exists( 'AWS_Table' ) ) :
170
 
171
  $this->fill_table( $post_id );
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  }
174
 
175
  /*
@@ -177,21 +219,10 @@ if ( ! class_exists( 'AWS_Table' ) ) :
177
  */
178
  private function extract_terms( $str ) {
179
 
180
- $str = $this->html2txt( $str );
181
-
182
- $str = esc_attr( $str );
183
- $str = stripslashes( $str );
184
- $str = str_replace( array( "\r", "\n" ), '', $str );
185
 
186
  // Avoid single A-Z.
187
- $str = preg_replace( '/\b\w{1}\b/i', " ", $str );
188
-
189
- $str = str_replace( array(
190
- "·",
191
- "…",
192
- "€",
193
- "&shy;"
194
- ), "", $str );
195
 
196
  $str = str_replace( array(
197
  ".",
23
 
24
  global $wpdb;
25
 
26
+ $this->table_name = $wpdb->prefix . AWS_INDEX_TABLE_NAME;
27
 
28
+ //add_action( 'wp_loaded', array( $this, 'check_table' ) );
29
 
30
  add_action( 'save_post', array( $this, 'update_table' ), 10, 3 );
31
 
32
+ add_action( 'aws_settings_saved', array( $this, 'clear_cache' ) );
33
+ add_action( 'aws_cache_clear', array( $this, 'clear_cache' ) );
34
+
35
+ add_action( 'create_term', array( &$this, 'term_changed' ), 10, 3 );
36
+ add_action( 'delete_term', array( &$this, 'term_changed' ), 10, 3 );
37
+ add_action( 'edit_term', array( &$this, 'term_changed' ), 10, 3 );
38
+
39
  add_action( 'wp_ajax_aws-reindex', array( $this, 'reindex_table' ) );
40
  add_action( 'wp_ajax_nopriv_aws-reindex', array( $this, 'reindex_table' ) );
41
 
42
+ add_action( 'wp_ajax_aws-clear-cache', array( &$this, 'clear_cache' ) );
43
+ add_action( 'wp_ajax_nopriv_aws-clear-cache', array( &$this, 'clear_cache' ) );
44
+
45
  }
46
 
47
  /*
55
 
56
  $this->check_table();
57
 
58
+ $this->clear_cache();
59
+
60
  }
61
 
62
  /*
182
 
183
  $this->fill_table( $post_id );
184
 
185
+ $this->clear_cache();
186
+
187
+ }
188
+
189
+ /*
190
+ * Fires when products terms are changed
191
+ */
192
+ public function term_changed( $term_id, $tt_id, $taxonomy ) {
193
+
194
+ if ( $taxonomy === 'product_cat' || $taxonomy === 'product_tag' ) {
195
+ do_action( 'aws_cache_clear' );
196
+ }
197
+
198
+ }
199
+
200
+ /*
201
+ * Clear search cache
202
+ */
203
+ public function clear_cache() {
204
+
205
+ global $wpdb;
206
+
207
+ $table_name = "aws_search_term_%";
208
+
209
+ $sql = "DELETE FROM $wpdb->options
210
+ WHERE option_name LIKE '{$table_name}'
211
+ ";
212
+
213
+ $wpdb->query( $sql );
214
+
215
  }
216
 
217
  /*
219
  */
220
  private function extract_terms( $str ) {
221
 
222
+ $str = AWS_Helpers::html2txt( $str );
 
 
 
 
223
 
224
  // Avoid single A-Z.
225
+ //$str = preg_replace( '/\b\w{1}\b/i', " ", $str );
 
 
 
 
 
 
 
226
 
227
  $str = str_replace( array(
228
  ".",
includes/options.php CHANGED
@@ -5,6 +5,18 @@
5
 
6
  $options = array();
7
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  $options['general'][] = array(
9
  "name" => __( "Text for search field", "aws" ),
10
  "desc" => __( "Text for search field placeholder.", "aws" ),
@@ -90,14 +102,14 @@ $options['general'][] = array(
90
  );
91
 
92
  $options['general'][] = array(
93
- "name" => __( "Mark words", "aws" ),
94
- "desc" => __( "Mark searching words in the result.", "aws" ),
95
  "id" => "mark_words",
96
  "value" => 'true',
97
  "type" => "radio",
98
  'choices' => array(
99
- 'true' => 'On',
100
- 'false' => 'Off'
101
  )
102
  );
103
 
5
 
6
  $options = array();
7
 
8
+ $options['general'][] = array(
9
+ "name" => __( "Cache results", "aws" ),
10
+ "desc" => __( "Turn off if you have old data in the search results after content of products was changed.<br><strong>CAUTION:</strong> can dramatically increase search speed", "aws" ),
11
+ "id" => "cache",
12
+ "value" => 'true',
13
+ "type" => "radio",
14
+ 'choices' => array(
15
+ 'true' => __( 'On', 'aws' ),
16
+ 'false' => __( 'Off', 'aws' ),
17
+ )
18
+ );
19
+
20
  $options['general'][] = array(
21
  "name" => __( "Text for search field", "aws" ),
22
  "desc" => __( "Text for search field placeholder.", "aws" ),
102
  );
103
 
104
  $options['general'][] = array(
105
+ "name" => __( "Description content", "aws" ),
106
+ "desc" => __( "What to show in product description?", "aws" ),
107
  "id" => "mark_words",
108
  "value" => 'true',
109
  "type" => "radio",
110
  'choices' => array(
111
+ 'true' => 'Smart scrapping sentences with searching terms from product description.',
112
+ 'false' => 'First N words of product description ( number of words that you choose below. )'
113
  )
114
  );
115
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: Mihail Barinov
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=GSE37FC4Y7CEY
4
  Tags: widget, plugin, woocommerce, search, product search, woocommerce search, ajax search, live search, custom search, ajax, shortcode, better search, relevance search, relevant search, search by sku, search plugin, shop, store, wordpress search, wp ajax search, wp search, wp search plugin, sidebar, ecommerce, merketing, products, category search, instant-search, search highlight, woocommerce advanced search, woocommerce live search, WooCommerce Plugin, woocommerce product search
5
  Requires at least: 4.0
6
- Tested up to: 4.5
7
- Stable tag: 1.05
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -64,6 +64,9 @@ Or insert this function inside php file ( often it used to insert form inside pa
64
 
65
  == Changelog ==
66
 
 
 
 
67
  = 1.05 =
68
  * Improve search speed
69
 
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=GSE37FC4Y7CEY
4
  Tags: widget, plugin, woocommerce, search, product search, woocommerce search, ajax search, live search, custom search, ajax, shortcode, better search, relevance search, relevant search, search by sku, search plugin, shop, store, wordpress search, wp ajax search, wp search, wp search plugin, sidebar, ecommerce, merketing, products, category search, instant-search, search highlight, woocommerce advanced search, woocommerce live search, WooCommerce Plugin, woocommerce product search
5
  Requires at least: 4.0
6
+ Tested up to: 4.5.2
7
+ Stable tag: 1.06
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
64
 
65
  == Changelog ==
66
 
67
+ = 1.06 =
68
+ * Cache search results to increase search speed
69
+
70
  = 1.05 =
71
  * Improve search speed
72