Ajax Search for WooCommerce - Version 0.9

Version Description

Download this release

Release Info

Developer damian-gora
Plugin Icon 128x128 Ajax Search for WooCommerce
Version 0.9
Comparing to
See all releases

Version 0.9

ajax-search-for-woocommerce.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Plugin Name: Ajax Search for WooCommerce
5
+ * Plugin URI: https://wordpress.org/plugins/ajax-search-for-woocommerce/
6
+ * Description: The plugin allows you to display the WooCommerce AJAX search form anywhere on the page.
7
+ * Version: 0.9
8
+ * Author: Damian Góra
9
+ * Author URI: http://damiangora.com
10
+ * Text Domain: ajax-search-for-woocommerce
11
+ * Domain Path: /languages/
12
+ *
13
+ */
14
+ // Exit if accessed directly
15
+ if ( !defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ if ( !class_exists( 'DGWT_WC_Ajax_Search' ) ) {
20
+
21
+ final class DGWT_WC_Ajax_Search {
22
+
23
+ private static $instance;
24
+ private $tnow;
25
+ public $settings;
26
+ public $search;
27
+ public $result_details;
28
+
29
+ public static function get_instance() {
30
+ if ( !isset( self::$instance ) && !( self::$instance instanceof DGWT_WC_Ajax_Search ) ) {
31
+ self::$instance = new DGWT_WC_Ajax_Search;
32
+ self::$instance->constants();
33
+ self::$instance->includes();
34
+ self::$instance->hooks();
35
+
36
+ // Set up localisation
37
+ self::$instance->load_textdomain();
38
+
39
+
40
+ self::$instance->settings = new DGWT_WCAS_Settings;
41
+ self::$instance->search = new DGWT_WCAS_Search;
42
+ self::$instance->result_details = new DGWT_WCAS_Result_Details;
43
+ }
44
+ self::$instance->tnow = time();
45
+
46
+ return self::$instance;
47
+ }
48
+
49
+ /**
50
+ * Constructor Function
51
+ */
52
+ private function __construct() {
53
+ self::$instance = $this;
54
+ }
55
+
56
+ /**
57
+ * Setup plugin constants
58
+ */
59
+ private function constants() {
60
+
61
+ $this->define( 'DGWT_WCAS_VERSION', '0.9' );
62
+ $this->define( 'DGWT_WCAS_NAME', 'Ajax Search for WooCommerce' );
63
+ $this->define( 'DGWT_WCAS_FILE', __FILE__ );
64
+ $this->define( 'DGWT_WCAS_DIR', plugin_dir_path( __FILE__ ) );
65
+ $this->define( 'DGWT_WCAS_URL', plugin_dir_url( __FILE__ ) );
66
+ $this->define( 'DGWT_WCAS_DOMAIN', 'woocommerce-ajax-search' );
67
+
68
+ $this->define( 'DGWT_WCAS_SETTINGS_KEY', 'dgwt_wcas_settings' );
69
+
70
+ $this->define( 'DGWT_WCAS_SEARCH_ACTION', 'dgwt_wcas_ajax_search' );
71
+ $this->define( 'DGWT_WCAS_RESULT_DETAILS_ACTION', 'dgwt_wcas_result_details' );
72
+
73
+ $this->define( 'DGWT_WCAS_WOO_PRODUCT_POST_TYPE', 'product' );
74
+ $this->define( 'DGWT_WCAS_WOO_PRODUCT_CATEGORY', 'product_cat' );
75
+ $this->define( 'DGWT_WCAS_WOO_PRODUCT_TAG', 'product_tag' );
76
+
77
+ $this->define( 'DGWT_WCAS_WC_AJAX_ENDPOINT', true );
78
+
79
+
80
+ $this->define( 'DGWT_WCAS_DEBUG', false );
81
+
82
+ //$this->define( 'DGWT_WCAS_PRO_VERSION', true );
83
+ }
84
+
85
+ /**
86
+ * Define constant if not already set
87
+ * @param string $name
88
+ * @param string|bool $value
89
+ */
90
+ private function define( $name, $value ) {
91
+ if ( !defined( $name ) ) {
92
+ define( $name, $value );
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Include required core files.
98
+ */
99
+ public function includes() {
100
+
101
+ require_once DGWT_WCAS_DIR . 'includes/functions.php';
102
+
103
+ require_once DGWT_WCAS_DIR . 'includes/install.php';
104
+
105
+ require_once DGWT_WCAS_DIR . 'includes/admin/settings/class-settings-api.php';
106
+ require_once DGWT_WCAS_DIR . 'includes/admin/settings/class-settings.php';
107
+
108
+ require_once DGWT_WCAS_DIR . 'includes/register-scripts.php';
109
+
110
+ require_once DGWT_WCAS_DIR . 'includes/admin/admin-menus.php';
111
+
112
+ require_once DGWT_WCAS_DIR . 'includes/widget.php';
113
+ require_once DGWT_WCAS_DIR . 'includes/style.php';
114
+ require_once DGWT_WCAS_DIR . 'includes/shortcode.php';
115
+ require_once DGWT_WCAS_DIR . 'includes/class-search.php';
116
+ require_once DGWT_WCAS_DIR . 'includes/class-result-details.php';
117
+
118
+ require_once DGWT_WCAS_DIR . 'includes/integrations/wp-tao.php';
119
+ }
120
+
121
+ /**
122
+ * Actions and filters
123
+ */
124
+ private function hooks() {
125
+
126
+ add_action( 'admin_init', array( $this, 'admin_scripts' ) );
127
+
128
+ //@todo create_cron_jobs action
129
+ //@todo fire_cron function init
130
+ }
131
+
132
+ /*
133
+ * Create cron if not exists
134
+ */
135
+
136
+ public function create_cron_jobs() {
137
+ //@todo create cron jobs
138
+ }
139
+
140
+ /*
141
+ * Enqueue admin sripts
142
+ */
143
+
144
+ public function admin_scripts() {
145
+ // Register CSS
146
+ wp_register_style( 'dgwt-wcas-admin-style', DGWT_WCAS_URL . 'assets/css/admin-style.css', array(), DGWT_WCAS_VERSION );
147
+
148
+
149
+
150
+ // Enqueue CSS
151
+ wp_enqueue_style( array(
152
+ 'dgwt-wcas-admin-style',
153
+ 'wp-color-picker'
154
+ ) );
155
+
156
+
157
+ wp_enqueue_script( 'wp-color-picker' );
158
+ }
159
+
160
+ /*
161
+ * Register text domain
162
+ */
163
+
164
+ private function load_textdomain() {
165
+ $lang_dir = dirname( plugin_basename( DGWT_WCAS_FILE ) ) . '/languages/';
166
+ load_plugin_textdomain( DGWT_WCAS_DOMAIN, false, $lang_dir );
167
+ }
168
+
169
+ }
170
+
171
+ }
172
+
173
+ // Init the plugin
174
+ function DGWT_WCAS() {
175
+ return DGWT_WC_Ajax_Search::get_instance();
176
+ }
177
+
178
+ add_action( 'plugins_loaded', 'DGWT_WCAS' );
assets/css/admin-style.css ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ .dgwt-wcas-settings-hr {
4
+ display: block;
5
+ border-bottom: 1px solid rgba(0,0,0,0.1);
6
+ }
7
+
8
+
9
+ .dgwt-wcas-settings-group > h2{
10
+ display: none;
11
+ }
12
+ .dgwt-wcas-admin-head {
13
+ margin: 30px 0 20px 5px;
14
+ }
15
+ .dgwt-wcas-admin-head h1 {
16
+ display: inline-block;
17
+ margin: 0 20px 0 0;
18
+ vertical-align: middle;
19
+ padding: 0;
20
+ }
21
+ .wp-core-ui .button.dgwt-wcas-button-preview {
22
+ vertical-align: middle;
23
+ }
24
+ .dgwt-wcas-button-preview .dashicons {
25
+ height: 22px;
26
+ vertical-align: middle;
27
+ margin-right: 5px;
28
+ }
29
+ .form-table td p.dgwt_wcas_settings-description-field {
30
+ color: #777;
31
+ display: inline-block;
32
+ font-size: 12px;
33
+ margin: 0 0 0 10px;
34
+ vertical-align: middle;
35
+ }
36
+
37
+ .dgwt_wcas_settings-group > h2{
38
+ display: none;
39
+ }
40
+
41
+
42
+ .dgwt-wcas-settings-info {
43
+ background: #fbfbfb none repeat scroll 0 0;
44
+ border: 1px solid #ddd;
45
+ padding: 15px;
46
+ }
47
+ .dgwt-wcas-settings-info h4 {
48
+ margin-top: 0;
49
+ font-size: 15px;
50
+ margin-bottom: 7px
51
+ }
52
+ .dgwt-wcas-settings-info p {
53
+ margin-bottom: 10px;
54
+ }
assets/css/style.css ADDED
@@ -0,0 +1,792 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ .dgwt-wcas-search-wrapp {
4
+ position: relative;
5
+ display: inline-block;
6
+ color: #444;
7
+ min-width: 300px;
8
+ max-width: 600px;
9
+ width: 100%;
10
+ text-align: left;
11
+ }
12
+ .widget .dgwt-wcas-search-wrapp {
13
+ display: block;
14
+ }
15
+
16
+ .dgwt-wcas-search-wrapp .product-title{
17
+ color: #333;
18
+ display: block;
19
+ line-height: 110%;
20
+ margin: 0;
21
+ }
22
+ .dgwt-wcas-tpd-image img{
23
+ margin: 0 15px 0 0!important;
24
+ display: block;
25
+ }
26
+ .dgwt_wcas_rtl .dgwt-wcas-tpd-image img {
27
+ margin: 0 0 0 15px!important;
28
+ }
29
+
30
+
31
+ .dgwt-wcas-default-preloader * {
32
+ box-sizing: border-box;
33
+ -o-box-sizing: border-box;
34
+ -ms-box-sizing: border-box;
35
+ -webkit-box-sizing: border-box;
36
+ -moz-box-sizing: border-box;
37
+ }
38
+
39
+ .dgwt-wcas-default-preloader {
40
+ width: 1em;
41
+ height: 1em;
42
+ font-size: 169px;
43
+ position: relative;
44
+ display:block;
45
+ margin: 56px auto;
46
+ }
47
+
48
+ .dgwt-wcas-default-preloader:before, .dgwt-wcas-default-preloader:after {
49
+ content: "";
50
+ top: 0;
51
+ display: block;
52
+ width: 1em;
53
+ height: 1em;
54
+ position: absolute;
55
+ border-width: 0.503em;
56
+ border-style: double;
57
+ border-color: transparent;
58
+ border-radius: 1em;
59
+ box-sizing: border-box;
60
+ -o-box-sizing: border-box;
61
+ -ms-box-sizing: border-box;
62
+ -webkit-box-sizing: border-box;
63
+ -moz-box-sizing: border-box;
64
+ animation: dgwt-wcas-spin 0.8s infinite;
65
+ -o-animation: dgwt-wcas-spin 0.8s infinite;
66
+ -ms-animation: dgwt-wcas-spin 0.8s infinite;
67
+ -webkit-animation: dgwt-wcas-spin 0.8s infinite;
68
+ -moz-animation: dgwt-wcas-spin 0.8s infinite;
69
+ }
70
+ .dgwt-wcas-default-preloader:after {
71
+ left: 0;
72
+ border-left-color: rgba(0,0,0,0.05);
73
+ }
74
+ .dgwt-wcas-default-preloader:before {
75
+ right: 0;
76
+ border-right-color: rgba(0,0,0,0.02);
77
+ animation-delay: -0.2025s;
78
+ -o-animation-delay: -0.2025s;
79
+ -ms-animation-delay: -0.2025s;
80
+ -webkit-animation-delay: -0.2025s;
81
+ -moz-animation-delay: -0.2025s;
82
+ }
83
+
84
+ @keyframes dgwt-wcas-spin {
85
+ from {
86
+ transform: rotate(360deg);
87
+ }
88
+ }
89
+
90
+ @-o-keyframes dgwt-wcas-spin {
91
+ from {
92
+ -o-transform: rotate(360deg);
93
+ }
94
+ }
95
+
96
+ @-ms-keyframes dgwt-wcas-spin {
97
+ from {
98
+ -ms-transform: rotate(360deg);
99
+ }
100
+ }
101
+
102
+ @-webkit-keyframes dgwt-wcas-spin {
103
+ from {
104
+ -webkit-transform: rotate(360deg);
105
+ }
106
+ }
107
+
108
+ @-moz-keyframes dgwt-wcas-spin {
109
+ from {
110
+ -moz-transform: rotate(360deg);
111
+ }
112
+ }
113
+ .dgwt-wcas-preloader-wrapp img {
114
+ margin: 10px auto 0 auto;
115
+ display: block;
116
+ max-width: 200px;
117
+ }
118
+
119
+ .dgwt-wcas-suggestions-wrapp {
120
+ background: #fff none repeat scroll 0 0;
121
+ border: 1px solid #ddd;
122
+ border-top: none;
123
+ padding: 0;
124
+ -webkit-box-sizing: border-box;
125
+ -moz-box-sizing: border-box;
126
+ box-sizing: border-box;
127
+ overflow-y: auto;
128
+ }
129
+
130
+ .dgwt-wcas-is-detail-box .dgwt-wcas-suggestions-wrapp {
131
+ max-width: 550px;
132
+ }
133
+ .dgwt-wcas-full-width.dgwt-wcas-is-detail-box .dgwt-wcas-suggestion{
134
+ padding: 8px 15px;
135
+ }
136
+
137
+ .dgwt-wcas-details-left .dgwt-wcas-suggestions-wrapp {
138
+ border-radius: 0 0 5px 0;
139
+ border-left-color: #eee;
140
+ }
141
+
142
+ .dgwt-wcas-details-right .dgwt-wcas-suggestions-wrapp {
143
+ border-radius: 5px 0 0 5px;
144
+ border-right-color: #eee;
145
+ }
146
+
147
+
148
+ .dgwt-wcas-suggestion {
149
+ cursor: pointer;
150
+ font-size: 12px;
151
+ line-height: 110%;
152
+ text-align: left;
153
+ padding: 7px 0;
154
+ position: relative;
155
+ border-bottom: 1px solid #dfdfdf;
156
+ display: flex;
157
+ flex-direction: column;
158
+ justify-content: center;
159
+ resize: vertical;
160
+ }
161
+ .dgwt-wcas-suggestion:after {
162
+ clear: both;
163
+ display: block;
164
+ content: '';
165
+ }
166
+
167
+ .dgwt-wcas-has-img .dgwt-wcas-suggestion {
168
+ padding: 12px 0;
169
+ }
170
+
171
+ .dgwt-wcas-st {
172
+ padding-left: 10px;
173
+ display: block;
174
+ color: #444;
175
+ font-size: 15px;
176
+ }
177
+
178
+ .dgwt-wcas-si {
179
+ position: absolute;
180
+ left: 10px;
181
+ top: 0;
182
+ width: 50px;
183
+ display: block;
184
+ height: 100%;
185
+ min-height: 50px;
186
+ }
187
+
188
+ .dgwt-wcas-si img {
189
+ background: #fff none repeat scroll 0 0;
190
+ border: 1px solid #e8e8e8;
191
+ border-radius: 3px;
192
+ bottom: 0;
193
+ display: block;
194
+ margin: auto;
195
+ padding: 2px;
196
+ position: absolute;
197
+ top: 0;
198
+ width: 50px;
199
+ }
200
+ .dgwt-wcas-content-wrapp {
201
+ padding-left: 60px;
202
+ }
203
+
204
+
205
+ .dgwt-wcas-sp {
206
+ color: #555;
207
+ font-size: 14px;
208
+ position: absolute;
209
+ right: 10px;
210
+ top: 5px;
211
+ vertical-align: middle;
212
+ line-height: 120%;
213
+ text-align: right;
214
+ }
215
+
216
+ .dgwt-wcas-search-form {
217
+ margin: 0;
218
+ padding: 0;
219
+ }
220
+
221
+ .dgwt-wcas-sp del {
222
+ opacity: 0.5;
223
+ font-size: 12px;
224
+ }
225
+
226
+ .dgwt-wcas-sd {
227
+ color: #777;
228
+ display: block;
229
+ padding-left: 15px;
230
+ line-height: 14px;
231
+ padding-right: 60px;
232
+ margin-top: 5px;
233
+ }
234
+
235
+ .dgwt-wcas-suggestion-selected {
236
+ background-color: #e9e9e9;
237
+ }
238
+ .dgwt-wcas-suggestion-selected:first-child {
239
+ border-top:none;
240
+ }
241
+
242
+ .dgwt_wcas_rtl .dgwt-wcas-suggestion {
243
+ padding-left: 0;
244
+ padding-right: 15px;
245
+ text-align: right;
246
+ }
247
+
248
+ .dgwt-wcas-full-width .dgwt-wcas-suggestion{
249
+ font-size: 15px;
250
+ padding: 5px 15px;
251
+ }
252
+
253
+ .dgwt-wcas-details-wrapp {
254
+ background: #fff none repeat scroll 0 0;
255
+ border: 1px solid #ddd;
256
+ border-top: none;
257
+ padding: 0;
258
+ width: 300px;
259
+ height: 340px;
260
+ -webkit-box-sizing: border-box;
261
+ -moz-box-sizing: border-box;
262
+ box-sizing: border-box;
263
+ z-index: 100;
264
+ min-height: 340px;
265
+ }
266
+
267
+ .dgwt-wcas-details-right .dgwt-wcas-details-wrapp {
268
+ border-left: none;
269
+ border-radius: 0 5px 5px 0;
270
+ }
271
+
272
+ .dgwt-wcas-details-left .dgwt-wcas-details-wrapp {
273
+ border-right: none;
274
+ border-radius: 5px 0 0 5px;
275
+ }
276
+
277
+
278
+ .dgwt-wcas-full-width .dgwt-wcas-suggestions-wrapp {
279
+ border-radius: 0 0 0 5px;
280
+ }
281
+ .dgwt-wcas-full-width .dgwt-wcas-details-wrapp {
282
+ border-radius: 0 0 5px 0;
283
+ }
284
+
285
+ .dgwt-wcas-details-inner {
286
+ padding: 15px 10px;
287
+ }
288
+
289
+
290
+ .woocommerce .dgwt-wcas-pd-rating .star-rating {
291
+ float: left;
292
+ margin-right: 5px;
293
+ font-size: 12px;
294
+ color: #CCAE72;
295
+ }
296
+ .woocommerce.dgwt_wcas_rtl .dgwt-wcas-pd-rating .star-rating {
297
+ float: right;
298
+ margin-left: 5px;
299
+ margin-right: 0;
300
+ }
301
+
302
+ .dgwt-wcas-datails-title{
303
+ border-bottom: 1px dashed #eee;
304
+ display: block;
305
+ margin-bottom: 15px;
306
+ padding-bottom: 5px;
307
+ font-size: 14px;
308
+ }
309
+ .dgwt-wcas-pd-title {
310
+ border-bottom: 1px dashed #eee;
311
+ margin-bottom: 15px;
312
+ padding-bottom: 5px;
313
+ display: block;
314
+ color: #202020;
315
+ text-decoration: none;
316
+ }
317
+ .dgwt-wcas-pd-title .product-title {
318
+ font-weight: 900;
319
+ color: #202020;
320
+ text-transform: uppercase;
321
+ letter-spacing: -1px;
322
+ margin: 0;
323
+ }
324
+
325
+
326
+ .dgwt-wcas-details-title-tax {
327
+ text-transform: uppercase;
328
+ font-weight: 900;
329
+ letter-spacing: -1px;
330
+ margin-right: 3px;
331
+ }
332
+
333
+ .dgwt-wcas-tax-product-details {
334
+ margin-bottom: 15px;
335
+ display: block;
336
+ text-decoration: none;
337
+ }
338
+
339
+ .dgwt-wcas-tax-product-details:after {
340
+ content: '';
341
+ clear: both;
342
+ display: block;
343
+ }
344
+
345
+ .dgwt-wcas-details-wrapp .dgwt-wcas-pd-title {
346
+ margin-bottom: 8px;
347
+ }
348
+ .dgwt-wcas-pd-rest {
349
+ display: flex;
350
+ flex-direction: column;
351
+ float: left;
352
+ height: 68px;
353
+ justify-content: center;
354
+ width: 190px;
355
+ }
356
+ .dgwt-wcas-tpd-image {
357
+ float: left;
358
+ width: 60px;
359
+ margin-right: 15px;
360
+ }
361
+ .dgwt-wcas-tpd-rest {
362
+ float: left;
363
+ max-width: 200px;
364
+ }
365
+
366
+ .dgwt-wcas-tpd-rest .product-title{
367
+ display: block;
368
+ line-height: 13px;
369
+ font-size: 13px;
370
+ font-weight: 500;
371
+ letter-spacing: 0;
372
+ margin: 0 0 8px;
373
+ overflow: hidden;
374
+ text-overflow: ellipsis;
375
+ text-transform: uppercase;
376
+ white-space: nowrap;
377
+ width: 145px;
378
+ }
379
+
380
+
381
+ .dgwt-wcas-pd-price {
382
+ margin-top: 10px;
383
+ font-size: 14px;
384
+ line-height: 13px;
385
+ overflow: hidden;
386
+ text-overflow: ellipsis;
387
+ white-space: nowrap;
388
+ width: 145px;
389
+ color: #777;
390
+ margin-top: 5px;
391
+ font-weight: lighter;
392
+ }
393
+
394
+ .dgwt-wcas-pd-price del .amount {
395
+ font-weight: lighter;
396
+ background: transparent;
397
+ font-size: 90%;
398
+ opacity: 0.6;
399
+ }
400
+ .dgwt-wcas-pd-price ins {
401
+ background: transparent;
402
+ text-decoration: none;
403
+ }
404
+ .dgwt-wcas-pd-rating {
405
+ font-size: 13px;
406
+ line-height: 13px;
407
+ }
408
+ .dgwt-wcas-pd-rating:after {
409
+ content: '';
410
+ clear: both;
411
+ display: block;
412
+ }
413
+
414
+ .dgwt-wcas-pd-review {
415
+ color: #777;
416
+ font-size: 11px;
417
+ line-height: 11px;
418
+ }
419
+
420
+ .dgwt-wcas-datails-title{
421
+ border-bottom: 1px dashed #eee;
422
+ display: block;
423
+ margin:5px 0 15px 0;
424
+ padding-bottom: 5px;
425
+ }
426
+ .dgwt-wcas-pd-title {
427
+ border-bottom: 1px dashed #eee;
428
+ margin-bottom: 15px;
429
+ padding-bottom: 5px;
430
+ display: block;
431
+
432
+ text-decoration: none;
433
+ }
434
+ .dgwt-wcas-pd-title .product-title {
435
+ font-weight: 900;
436
+
437
+ text-transform: uppercase;
438
+ letter-spacing: -1px;
439
+ }
440
+
441
+
442
+ .dgwt-wcas-details-title-tax {
443
+ text-transform: uppercase;
444
+ font-weight: 900;
445
+ letter-spacing: -1px;
446
+ margin-right: 3px;
447
+
448
+ }
449
+ .dgwt_wcas_rtl .dgwt-wcas-details-title-tax {
450
+ margin: 0 0 0 3px;
451
+ float: right;
452
+ }
453
+
454
+ .dgwt-wcas-tax-product-details {
455
+ margin-bottom: 15px;
456
+ display: block;
457
+ }
458
+
459
+ .dgwt-wcas-tax-product-details:after, .dgwt-wcas-pd-details:after {
460
+ content: '';
461
+ clear: both;
462
+ display: block;
463
+ }
464
+
465
+ .dgwt-wcas-tpd-image, .dgwt-wcas-pd-image {
466
+ float: left;
467
+ width: 70px;
468
+ margin-right: 15px;
469
+ padding: 4px;
470
+ background-color: #fff;
471
+ border:1px solid #e8e8e8;
472
+ border-radius: 4px;
473
+ }
474
+ .dgwt-wcas-tpd-image img, .dgwt-wcas-pd-image img{
475
+ display: block;
476
+ }
477
+
478
+ .dgwt_wcas_rtl .dgwt-wcas-tpd-image, .dgwt_wcas_rtl .dgwt-wcas-pd-image{
479
+ float: right;
480
+ margin-right: 0;
481
+ margin-left: 15px;
482
+ }
483
+
484
+ .dgwt_wcas_rtl .dgwt-wcas-tpd-rest, .dgwt_wcas_rtl .dgwt-wcas-pd-rest {
485
+ float: right;
486
+ max-width: 200px;
487
+ }
488
+
489
+ input[type="search"].dgwt-wcas-search-input, input[type="text"].dgwt-wcas-search-input {
490
+ -webkit-transition: none;
491
+ -moz-transition: none;
492
+ -ms-transition: none;
493
+ -o-transition: none;
494
+ transition: none;
495
+ }
496
+
497
+ .dgwt-wcas-pd-desc {
498
+ font-size: 13px;
499
+ line-height: 130%;
500
+ margin: 12px 0;
501
+ }
502
+
503
+ .dgwt-wcas-pd-addtc {
504
+ margin: 10px;
505
+ text-align: right;
506
+ }
507
+
508
+ .dgwt-wcas-pd-addtc a {
509
+ margin-bottom: 5px;
510
+ }
511
+
512
+
513
+ input[type="submit"].dgwt-wcas-search-submit, button.dgwt-wcas-search-submit{
514
+ position: relative;
515
+ }
516
+
517
+
518
+ .dgwt-wcas-ico-loupe {
519
+ bottom: 0;
520
+ left: 0;
521
+ margin: auto;
522
+ position: absolute;
523
+ right: 0;
524
+ top: 0;
525
+ height: 65%;
526
+ display: block;
527
+ }
528
+ .dgwt-wcas-preloader {
529
+ cursor: pointer;
530
+ height: 100%;
531
+ position: absolute;
532
+ right: 0;
533
+ top: 0;
534
+ width: 40px;
535
+ z-index: 1;
536
+ background-repeat: no-repeat;
537
+ background-position: right 15px center;
538
+ background-size: auto 44%;
539
+ }
540
+ .dgwt-wcas-inner-preloader {
541
+ background-image: url('../img/preloader.png');
542
+ background-repeat: no-repeat;
543
+ background-position: right 15px center;
544
+ background-size: auto 50%;
545
+ }
546
+
547
+ .dgwt-wcas-close{
548
+ background-image: url('../img/close.png');
549
+ background-repeat: no-repeat;
550
+ background-position: right 15px center;
551
+ background-size: auto 35%;
552
+ opacity: 0.6;
553
+ -webkit-transition: all 160ms ease-in-out;
554
+ -moz-transition: all 160ms ease-in-out;
555
+ -ms-transition: all 160ms ease-in-out;
556
+ -o-transition: all 160ms ease-in-out;
557
+ transition: all 160ms ease-in-out;
558
+ }
559
+
560
+ .dgwt-wcas-close:hover {
561
+ opacity: 0.3;
562
+ }
563
+
564
+ @media screen and (max-width: 992px) {
565
+ .dgwt-wcas-is-detail-box .dgwt-wcas-suggestions-wrapp {
566
+ max-width: none;
567
+ }
568
+ }
569
+
570
+ .dgwt-wcas-st strong{
571
+ font-weight: bold;
572
+ }
573
+
574
+ .screen-reader-text {
575
+ clip: rect(1px, 1px, 1px, 1px);
576
+ height: 1px;
577
+ overflow: hidden;
578
+ position: absolute !important;
579
+ width: 1px;
580
+ }
581
+ .dgwt-wcas-sf-wrapp:before, .dgwt-wcas-sf-wrapp:after {
582
+ content:"";
583
+ display:table;
584
+ }
585
+ .dgwt-wcas-sf-wrapp:after {
586
+ clear:both;
587
+ }
588
+ .dgwt-wcas-sf-wrapp {
589
+ zoom:1;
590
+ width: 100%;
591
+ margin: 0;
592
+ position: relative;
593
+ background: #444;
594
+ background: rgba(0,0,0,.2);
595
+ border-radius: 10px;
596
+ box-shadow: 0 1px 1px rgba(0,0,0,.4) inset, 0 1px 0 rgba(255,255,255,.2);
597
+ }
598
+
599
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input{
600
+ width: 100%;
601
+ height: 40px;
602
+ padding: 10px 15px;
603
+ border: 0;
604
+ background: #fff;
605
+ border:1px solid #ddd;
606
+ border-radius: 3px;
607
+ }
608
+ .dgwt-wcas-open .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input {
609
+ border-radius: 3px 3px 0 0;
610
+ }
611
+
612
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input:focus {
613
+ outline: 0;
614
+ background: #fff;
615
+ box-shadow: 0 0 8px 1px rgba(0,0,0,.1);
616
+ }
617
+
618
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input::-webkit-input-placeholder {
619
+ color: #999;
620
+ font-weight: normal;
621
+ font-style: italic;
622
+ }
623
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input:-moz-placeholder {
624
+ color: #999;
625
+ font-weight: normal;
626
+ font-style: italic;
627
+ }
628
+
629
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input::-moz-placeholder {
630
+ color: #999;
631
+ font-weight: normal;
632
+ font-style: italic;
633
+ }
634
+
635
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input:-ms-input-placeholder {
636
+ color: #999;
637
+ font-weight: normal;
638
+ font-style: italic;
639
+ }
640
+
641
+ /* Form submit button */
642
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit {
643
+ overflow: visible;
644
+ position: absolute;
645
+ border: 0;
646
+ padding: 0;
647
+ cursor: pointer;
648
+ height: 40px;
649
+ min-width: 50px;
650
+ right: 0;
651
+ top: 0;
652
+ padding: 0 15px;
653
+ color: #fff;
654
+ -webkit-transition: all 250ms ease-in-out;
655
+ -moz-transition: all 250ms ease-in-out;
656
+ -ms-transition: all 250ms ease-in-out;
657
+ -o-transition: all 250ms ease-in-out;
658
+ transition: all 250ms ease-in-out;
659
+ text-transform: uppercase;
660
+ background-color: #96588A;
661
+ border-radius: 3px;
662
+ text-shadow: 0 -1px 0 rgba(0, 0 ,0, .3);
663
+ }
664
+ .dgwt-wcas-open .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit{
665
+ border-radius: 3px 3px 0 3px;
666
+ }
667
+
668
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:hover{
669
+ opacity: 0.7;
670
+ }
671
+
672
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:active,
673
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:focus{
674
+ opacity: 0.7;
675
+ outline: 0;
676
+ }
677
+
678
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:before { /* left arrow */
679
+ content: '';
680
+ position: absolute;
681
+ border-width: 8px 8px 8px 0;
682
+ border-style: solid solid solid none;
683
+ border-color: transparent #96588A transparent;
684
+ top: 12px;
685
+ left: -6px;
686
+ -webkit-transition: all 250ms ease-in-out;
687
+ -moz-transition: all 250ms ease-in-out;
688
+ -ms-transition: all 250ms ease-in-out;
689
+ -o-transition: all 250ms ease-in-out;
690
+ transition: all 250ms ease-in-out;
691
+ }
692
+
693
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:hover:before{
694
+ border-right-color: #96588A;
695
+ }
696
+
697
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:focus:before,
698
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:active:before{
699
+ border-right-color: #96588A;
700
+ }
701
+
702
+ .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit::-moz-focus-inner { /* remove extra button spacing for Mozilla Firefox */
703
+ border: 0;
704
+ padding: 0;
705
+ }
706
+
707
+ .dgwt-wcas-ico-loupe {
708
+ fill:#fff;
709
+ }
710
+
711
+ .dgwt-wcas-has-img .dgwt-wcas-suggestion {
712
+ min-height: 60px;
713
+ }
714
+ .dgwt-wcas-details-inner .added_to_cart {
715
+ display: block;
716
+ }
717
+
718
+ /*------------------------------------------------------
719
+ Has image
720
+ ---------------------------------------------------------*/
721
+ .dgwt-wcas-has-img .dgwt-wcas-sp > *,
722
+ .dgwt-wcas-has-desc .dgwt-wcas-sp > *{
723
+ display: block;
724
+ }
725
+ .dgwt-wcas-has-img .dgwt-wcas-sp,
726
+ .dgwt-wcas-has-desc .dgwt-wcas-sp{
727
+ top: 12px;
728
+ }
729
+
730
+ /*------------------------------------------------------
731
+ Specific styles for details box
732
+ ---------------------------------------------------------*/
733
+ .dgwt-wcas-is-details .dgwt-wcas-content-wrapp{
734
+ display: flex;
735
+ flex-direction: column;
736
+ height: 100%;
737
+ justify-content: center;
738
+ resize: vertical;
739
+ padding-left: 20px;
740
+ }
741
+
742
+ .dgwt-wcas-is-details .dgwt-wcas-suggestions-wrapp {
743
+ min-height: 340px;
744
+ }
745
+
746
+ .dgwt-wcas-is-details .dgwt-wcas-has-img .dgwt-wcas-suggestion {
747
+ min-height: 40px;
748
+ }
749
+ .dgwt-wcas-is-details .dgwt-wcas-suggestions-wrapp {
750
+ overflow: visible;
751
+ }
752
+ .dgwt-wcas-is-details .dgwt-wcas-si{
753
+ min-height: 40px;
754
+ }
755
+
756
+ .dgwt-wcas-is-details .dgwt-wcas-si img {
757
+ width: 30px;
758
+ }
759
+ .dgwt-wcas-is-details .dgwt-wcas-sp {
760
+ display: flex;
761
+ top: 0;
762
+ flex-direction: column;
763
+ height: 100%;
764
+ justify-content: center;
765
+ resize: vertical;
766
+ }
767
+ .dgwt-wcas-is-details .dgwt-wcas-sd {
768
+ color: #777;
769
+ font-size: 11px;
770
+ line-height: 100%;
771
+ }
772
+ .dgwt-wcas-has-img .dgwt-wcas-suggestion[data-taxonomy='product_cat'],
773
+ .dgwt-wcas-has-img .dgwt-wcas-suggestion[data-taxonomy='product_tag']{
774
+ padding-left: 15px;
775
+ min-height: 0;
776
+ }
777
+ .dgwt-wcas-has-img .dgwt-wcas-suggestion[data-taxonomy='product_cat'] .dgwt-wcas-st,
778
+ .dgwt-wcas-has-img .dgwt-wcas-suggestion[data-taxonomy='product_tag'] .dgwt-wcas-st{
779
+ padding-left: 0;
780
+ }
781
+
782
+ .dgwt-wcas-no-submit .dgwt-wcas-ico-loupe {
783
+ height: 50%;
784
+ left: 12px;
785
+ right: auto;
786
+ opacity: 0.5;
787
+ fill:#000;
788
+ }
789
+
790
+ .dgwt-wcas-no-submit .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input {
791
+ padding: 10px 15px 10px 40px;
792
+ }
assets/img/admin-icon.png ADDED
Binary file
assets/img/admin-icon.svg ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg
4
+ version="1.1"
5
+ class="dgwt-wcas-ico-loupe"
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ xmlns:xlink="http://www.w3.org/1999/xlink"
8
+ x="0px"
9
+ y="0px"
10
+ fill="#FFFFFF"
11
+ width="16px"
12
+ height="16px"
13
+ viewBox="0 0 51 51"
14
+ xml:space="preserve">
15
+
16
+ <path d="M51.539,49.356L37.247,35.065c3.273-3.74,5.272-8.623,5.272-13.983c0-11.742-9.518-21.26-21.26-21.26
17
+ S0,9.339,0,21.082s9.518,21.26,21.26,21.26c5.361,0,10.244-1.999,13.983-5.272l14.292,14.292L51.539,49.356z M2.835,21.082
18
+ c0-10.176,8.249-18.425,18.425-18.425s18.425,8.249,18.425,18.425S31.436,39.507,21.26,39.507S2.835,31.258,2.835,21.082z"/>
19
+ </svg>
assets/img/close.png ADDED
Binary file
assets/img/details-box-sample.jpg ADDED
@@ -0,0 +1 @@
 
1
+
assets/img/preloader.png ADDED
Binary file
assets/js/jquery.dgwt-wcas.js ADDED
@@ -0,0 +1,1425 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Ajax Autocomplete for jQuery, version 1.2.24
3
+ * (c) 2015 Tomas Kirda
4
+ *
5
+ * Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
6
+ * For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete
7
+ *
8
+ * Modified by Damian Góra: http://damiangora.com
9
+ */
10
+
11
+ /*jslint browser: true, white: true, plusplus: true, vars: true */
12
+ /*global define, window, document, jQuery, exports, require */
13
+
14
+ // Expose plugin as an AMD module if AMD loader is present:
15
+ ( function ( factory ) {
16
+ 'use strict';
17
+ if ( typeof define === 'function' && define.amd ) {
18
+ // AMD. Register as an anonymous module.
19
+ define( [ 'jquery' ], factory );
20
+ } else if ( typeof exports === 'object' && typeof require === 'function' ) {
21
+ // Browserify
22
+ factory( require( 'jquery' ) );
23
+ } else {
24
+ // Browser globals
25
+ factory( jQuery );
26
+ }
27
+ }( function ( $ ) {
28
+ 'use strict';
29
+
30
+ var utils = ( function () {
31
+ return {
32
+ escapeRegExChars: function ( value ) {
33
+ return value.replace( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&" );
34
+ },
35
+ createNode: function ( containerClass ) {
36
+ var div = document.createElement( 'div' );
37
+ div.className = containerClass;
38
+ div.style.position = 'absolute';
39
+ div.style.display = 'none';
40
+ return div;
41
+ }
42
+ };
43
+ }() ),
44
+ keys = {
45
+ ESC: 27,
46
+ TAB: 9,
47
+ RETURN: 13,
48
+ LEFT: 37,
49
+ UP: 38,
50
+ RIGHT: 39,
51
+ DOWN: 40
52
+ };
53
+
54
+ function Autocomplete( el, options ) {
55
+ var noop = function () { },
56
+ that = this,
57
+ defaults = {
58
+ ajaxSettings: { },
59
+ autoSelectFirst: false,
60
+ appendTo: document.body,
61
+ serviceUrl: null,
62
+ lookup: null,
63
+ onSelect: null,
64
+ onMouseOver: null,
65
+ onMouseLeave: null,
66
+ width: 'auto',
67
+ containerDetailsWidth: 'auto',
68
+ showDetailsPanel: false,
69
+ showImage: false,
70
+ showPrice: false,
71
+ showDescription: false,
72
+ showSaleBadge: false,
73
+ showFeaturedBadge: false,
74
+ saleBadgeText: 'sale',
75
+ featuredBadgeText: 'featured',
76
+ minChars: 1,
77
+ maxHeight: 1000,
78
+ deferRequestBy: 0,
79
+ params: { },
80
+ formatResult: Autocomplete.formatResult,
81
+ delimiter: null,
82
+ zIndex: 9999,
83
+ type: 'GET',
84
+ noCache: false,
85
+ is_rtl: false,
86
+ onSearchStart: noop,
87
+ onSearchComplete: noop,
88
+ onSearchError: noop,
89
+ preserveInput: false,
90
+ wrapperaClass: 'dgwt-wcas-search-wrapp',
91
+ containerClass: 'dgwt-wcas-suggestions-wrapp',
92
+ containerDetailsClass: 'dgwt-wcas-details-wrapp',
93
+ cointainerDetailsPos: 'right',
94
+ preloaderClass: 'dgwt-wcas-preloader',
95
+ closeTrigger: 'dgwt-wcas-close',
96
+ tabDisabled: false,
97
+ dataType: 'text',
98
+ currentRequest: null,
99
+ triggerSelectOnValidInput: true,
100
+ preventBadQueries: true,
101
+ lookupFilter: function ( suggestion, originalQuery, queryLowerCase ) {
102
+ return suggestion.value.toLowerCase().indexOf( queryLowerCase ) !== -1;
103
+ },
104
+ paramName: 'query',
105
+ transformResult: function ( response ) {
106
+ return typeof response === 'string' ? $.parseJSON( response ) : response;
107
+ },
108
+ showNoSuggestionNotice: false,
109
+ noSuggestionNotice: 'No results',
110
+ orientation: 'bottom',
111
+ forceFixPosition: false
112
+ };
113
+
114
+ // Shared variables:
115
+ that.element = el;
116
+ that.el = $( el );
117
+ that.suggestions = [ ];
118
+ that.badQueries = [ ];
119
+ that.selectedIndex = -1;
120
+ that.currentValue = that.element.value;
121
+ that.intervalId = 0;
122
+ that.cachedResponse = { };
123
+ that.cachedDetails = { };
124
+ that.onChangeInterval = null;
125
+ that.onChange = null;
126
+ that.isLocal = false;
127
+ that.suggestionsContainer = null;
128
+ that.detailsContainer = null;
129
+ that.noSuggestionsContainer = null;
130
+ that.options = $.extend( { }, defaults, options );
131
+ that.classes = {
132
+ selected: 'dgwt-wcas-suggestion-selected',
133
+ suggestion: 'dgwt-wcas-suggestion'
134
+ };
135
+ that.hint = null;
136
+ that.hintValue = '';
137
+ that.selection = null;
138
+
139
+ // Initialize and set options:
140
+ that.initialize();
141
+ that.setOptions( options );
142
+ }
143
+
144
+ Autocomplete.utils = utils;
145
+
146
+ $.Autocomplete = Autocomplete;
147
+
148
+ Autocomplete.formatResult = function ( suggestion, currentValue ) {
149
+ var pattern = '(' + utils.escapeRegExChars( currentValue ) + ')';
150
+
151
+ return suggestion.value
152
+ .replace( new RegExp( pattern, 'gi' ), '<strong>$1<\/strong>' )
153
+ .replace( /&/g, '&amp;' )
154
+ .replace( /</g, '&lt;' )
155
+ .replace( />/g, '&gt;' )
156
+ .replace( /"/g, '&quot;' )
157
+ .replace( /&lt;(\/?strong)&gt;/g, '<$1>' );
158
+ };
159
+
160
+ Autocomplete.prototype = {
161
+ killerFn: null,
162
+ initialize: function () {
163
+ var that = this,
164
+ suggestionSelector = '.' + that.classes.suggestion,
165
+ selected = that.classes.selected,
166
+ options = that.options,
167
+ container,
168
+ containerDetails,
169
+ closeTrigger = '.' + options.closeTrigger;
170
+
171
+ // Remove autocomplete attribute to prevent native suggestions:
172
+ that.element.setAttribute( 'autocomplete', 'off' );
173
+
174
+ that.killerFn = function ( e ) {
175
+ if (
176
+ $( e.target ).closest( '.' + that.options.containerClass ).length === 0 &&
177
+ $( e.target ).closest( '.' + that.options.containerDetailsClass ).length === 0
178
+ ) {
179
+ that.killSuggestions();
180
+ that.disableKillerFn();
181
+ }
182
+ };
183
+
184
+ // html() deals with many types: htmlString or Element or Array or jQuery
185
+ that.noSuggestionsContainer = $( '<div class="dgwt-wcas-no-suggestion"></div>' )
186
+ .html( this.options.noSuggestionNotice ).get( 0 );
187
+
188
+ // Create sugestions container
189
+ that.suggestionsContainer = Autocomplete.utils.createNode( options.containerClass );
190
+
191
+ container = $( that.suggestionsContainer );
192
+
193
+ container.appendTo( that.el.closest( '.' + options.wrapperaClass ) );
194
+
195
+ // Add conditiona classes
196
+ if ( options.showImage === true )
197
+ container.addClass( 'dgwt-wcas-has-img' );
198
+ // Price
199
+ if ( options.showPrice === true )
200
+ container.addClass( 'dgwt-wcas-has-price' );
201
+ // Description
202
+ if ( options.showDescription === true )
203
+ container.addClass( 'dgwt-wcas-has-desc' );
204
+
205
+
206
+ // Only set width if it was provided:
207
+ if ( options.width !== 'auto' ) {
208
+ container.width( options.width );
209
+ }
210
+
211
+ // Create suggestions details container
212
+ if ( options.showDetailsPanel === true ) {
213
+ that.detailsContainer = Autocomplete.utils.createNode( options.containerDetailsClass );
214
+
215
+ containerDetails = $( that.detailsContainer );
216
+
217
+ containerDetails.appendTo( that.el.closest( '.' + options.wrapperaClass ) );
218
+ }
219
+
220
+
221
+ // Listen for mouse over event on suggestions list:
222
+ container.on( 'mouseover.autocomplete', suggestionSelector, function () {
223
+ that.onMouseOver( $( this ).data( 'index' ) );
224
+ that.activate( $( this ).data( 'index' ) );
225
+ } );
226
+
227
+ // Deselect active element when mouse leaves suggestions container:
228
+ container.on( 'mouseout.autocomplete', function () {
229
+ //that.selectedIndex = -1;
230
+ // container.children( '.' + selected ).removeClass( selected );
231
+ } );
232
+
233
+ // Listen for click event on suggestions list:
234
+ $( document ).on( 'click.autocomplete', closeTrigger, function ( e ) {
235
+ that.killerFn( e );
236
+ that.clear( e );
237
+ $( this ).removeClass( options.closeTrigger );
238
+ that.el.val( '' ).focus();
239
+ } );
240
+
241
+ // Listen for click close button:
242
+ container.on( 'click.autocomplete', suggestionSelector, function () {
243
+ that.select( $( this ).data( 'index' ) );
244
+ } );
245
+
246
+ that.fixPositionCapture = function () {
247
+ if ( that.visible ) {
248
+ that.fixPosition();
249
+ }
250
+ };
251
+
252
+ $( window ).on( 'resize.autocomplete', that.fixPositionCapture );
253
+
254
+ that.el.on( 'keydown.autocomplete', function ( e ) {
255
+ that.onKeyPress( e );
256
+ } );
257
+ that.el.on( 'keyup.autocomplete', function ( e ) {
258
+ that.onKeyUp( e );
259
+ } );
260
+ that.el.on( 'blur.autocomplete', function () {
261
+ that.onBlur();
262
+ } );
263
+ that.el.on( 'focus.autocomplete', function () {
264
+ that.onFocus();
265
+ } );
266
+ that.el.on( 'change.autocomplete', function ( e ) {
267
+ that.onKeyUp( e );
268
+ } );
269
+ that.el.on( 'input.autocomplete', function ( e ) {
270
+ that.onKeyUp( e );
271
+ } );
272
+ },
273
+ onFocus: function () {
274
+ var that = this;
275
+ that.fixPosition();
276
+ if ( that.options.minChars === 0 && that.el.val().length === 0 ) {
277
+ that.onValueChange();
278
+ }
279
+ },
280
+ onBlur: function () {
281
+ this.enableKillerFn();
282
+ },
283
+ abortAjax: function () {
284
+ var that = this;
285
+ if ( that.currentRequest ) {
286
+ that.currentRequest.abort();
287
+ that.currentRequest = null;
288
+ }
289
+ },
290
+ setOptions: function ( suppliedOptions ) {
291
+ var that = this,
292
+ options = that.options;
293
+
294
+ $.extend( options, suppliedOptions );
295
+
296
+ that.isLocal = $.isArray( options.lookup );
297
+
298
+ if ( that.isLocal ) {
299
+ options.lookup = that.verifySuggestionsFormat( options.lookup );
300
+ }
301
+
302
+ options.orientation = that.validateOrientation( options.orientation, 'bottom' );
303
+
304
+ // Adjust height, width and z-index:
305
+ $( that.suggestionsContainer ).css( {
306
+ 'max-height': options.maxHeight + 'px',
307
+ 'width': options.width + 'px',
308
+ 'z-index': options.zIndex
309
+ } );
310
+
311
+ // Add classes
312
+ if ( options.showDetailsPanel === true ) {
313
+ jQuery( that.suggestionsContainer ).parent().addClass( 'dgwt-wcas-is-details' );
314
+ }
315
+
316
+ that.options.onSearchComplete = function () {
317
+ that.preloader( 'hide', $( '.' + options.preloaderClass ), 'dgwt-wcas-inner-preloader', dgwt_wcas.preloader_url, true );
318
+ that.preloader( 'show', $( '.' + options.preloaderClass ), options.closeTrigger, '', true );
319
+ };
320
+
321
+
322
+ },
323
+ clearCache: function () {
324
+ this.cachedResponse = { };
325
+ this.cachedDetails = { };
326
+ this.badQueries = [ ];
327
+ },
328
+ clear: function () {
329
+ this.clearCache();
330
+ this.currentValue = '';
331
+ this.suggestions = [ ];
332
+ },
333
+ disable: function () {
334
+ var that = this;
335
+ that.disabled = true;
336
+ clearInterval( that.onChangeInterval );
337
+ that.abortAjax();
338
+ },
339
+ enable: function () {
340
+ this.disabled = false;
341
+ },
342
+ fixPosition: function () {
343
+ // Use only when container has already its content
344
+ var that = this,
345
+ options = that.options,
346
+ heigh = 0,
347
+ $container = $( that.suggestionsContainer ),
348
+ $containerDetails = $( that.detailsContainer ),
349
+ containerParent = $container.parent().get( 0 );
350
+ // Fix position automatically when appended to body.
351
+ // In other cases force parameter must be given.
352
+ if ( containerParent !== document.body && !that.options.forceFixPosition ) {
353
+ return;
354
+ }
355
+
356
+ // Choose orientation
357
+ var orientation = that.options.orientation,
358
+ containerHeight = $container.outerHeight(),
359
+ height = that.el.outerHeight(),
360
+ offset = that.el.offset(),
361
+ styles = { 'top': offset.top, 'left': offset.left };
362
+
363
+ if ( orientation === 'auto' ) {
364
+ var viewPortHeight = $( window ).height(),
365
+ scrollTop = $( window ).scrollTop(),
366
+ topOverflow = -scrollTop + offset.top - containerHeight,
367
+ bottomOverflow = scrollTop + viewPortHeight - ( offset.top + height + containerHeight );
368
+
369
+ orientation = ( Math.max( topOverflow, bottomOverflow ) === topOverflow ) ? 'top' : 'bottom';
370
+ }
371
+
372
+ if ( orientation === 'top' ) {
373
+ styles.top += -containerHeight;
374
+ } else {
375
+ styles.top += height;
376
+ }
377
+
378
+ // If container is not positioned to body,
379
+ // correct its position using offset parent offset
380
+ if ( containerParent !== document.body ) {
381
+ var opacity = $container.css( 'opacity' ),
382
+ parentOffsetDiff;
383
+
384
+ if ( !that.visible ) {
385
+ $container.css( 'opacity', 0 ).show();
386
+ }
387
+
388
+ parentOffsetDiff = $container.offsetParent().offset();
389
+ styles.top -= parentOffsetDiff.top;
390
+ styles.left -= parentOffsetDiff.left;
391
+
392
+ if ( !that.visible ) {
393
+ $container.css( 'opacity', opacity ).hide();
394
+ }
395
+ }
396
+
397
+ // -2px to account for suggestions border.
398
+ if ( that.options.width === 'auto' ) {
399
+ styles.width = ( that.el.outerWidth() - 2 ) + 'px';
400
+ }
401
+
402
+ $container.css( styles );
403
+
404
+ },
405
+ fixPositionDetailsBox: function () {
406
+
407
+ var that = this,
408
+ containerDetails = $( that.detailsContainer );
409
+
410
+ if ( containerDetails.length == 0 ) {
411
+ return false;
412
+ }
413
+
414
+ var windowWidth = $( window ).width(),
415
+ container = containerDetails.parent(),
416
+ containerSugg = containerDetails.prev(),
417
+ cDWidth = containerDetails.width(),
418
+ cOffset = containerDetails.offset(),
419
+ leftBorderCrossed = false,
420
+ rightBorderCrossed = false,
421
+ maxWidth = 550;
422
+
423
+
424
+ // Not set position on the bigger search form
425
+ if ( container.width() >= maxWidth ) {
426
+ return;
427
+ }
428
+
429
+
430
+ // Right border crossed
431
+ if ( windowWidth < ( cOffset.left + cDWidth ) ) {
432
+
433
+ container.removeClass( 'dgwt-wcas-details-right' );
434
+ container.addClass( 'dgwt-wcas-details-left' );
435
+
436
+ containerDetails.css( 'left', '-' + containerDetails.outerWidth() + 'px' );
437
+
438
+ }
439
+
440
+ // Left border crossed
441
+ if ( cOffset.left < 1 ) {
442
+
443
+ container.removeClass( 'dgwt-wcas-details-left' );
444
+ container.addClass( 'dgwt-wcas-details-right' );
445
+
446
+ containerDetails.css( 'left', containerSugg.outerWidth() + 'px' );
447
+ }
448
+ },
449
+ fixHeight: function ( counter, largestHeight ) {
450
+
451
+ var that = this,
452
+ options = that.options;
453
+
454
+ if ( options.showDetailsPanel != true ) {
455
+ return false;
456
+ }
457
+
458
+ var contSuggestions = $( '.' + options.containerClass ),
459
+ contDetails = $( '.' + options.containerDetailsClass ),
460
+ sH = 0,
461
+ dH = 0,
462
+ largestHeight;
463
+
464
+ // Height inside a suggestions container
465
+ $( '.' + options.containerClass + '> *' ).each( function () {
466
+ sH = sH + $( this ).outerHeight();
467
+ } );
468
+
469
+ // Height inside a suggestions container
470
+ $( '.' + options.containerDetailsClass + '> *' ).each( function () {
471
+ dH = dH + $( this ).outerHeight();
472
+ } );
473
+
474
+ if ( sH >= dH ) {
475
+ largestHeight = sH;
476
+ } else {
477
+ largestHeight = dH;
478
+ }
479
+
480
+ if ( largestHeight > sH || largestHeight > dH ) {
481
+ contSuggestions.css( 'height', largestHeight + 'px' );
482
+ contDetails.css( 'height', largestHeight + 'px' );
483
+ }
484
+
485
+ if ( typeof counter === 'undefined' ) {
486
+ counter = 0;
487
+ }
488
+
489
+ // Fix delay
490
+ if ( counter < 5 ) {
491
+
492
+ setTimeout( function () {
493
+ that.fixHeight( counter + 1, largestHeight );
494
+
495
+ }, 30 );
496
+ } else {
497
+ counter = 0;
498
+ }
499
+ },
500
+ enableKillerFn: function () {
501
+ var that = this;
502
+ $( document ).on( 'click.autocomplete', that.killerFn );
503
+ },
504
+ disableKillerFn: function () {
505
+ var that = this;
506
+ $( document ).off( 'click.autocomplete', that.killerFn );
507
+ },
508
+ killSuggestions: function () {
509
+ var that = this,
510
+ containerParent = $( that.suggestionsContainer ).parent();
511
+ that.stopKillSuggestions();
512
+ that.intervalId = window.setInterval( function () {
513
+ if ( that.visible ) {
514
+ that.el.val( that.currentValue );
515
+ that.hide();
516
+ containerParent.removeClass( 'dgwt-wcas-open' );
517
+ }
518
+
519
+ that.stopKillSuggestions();
520
+ }, 50 );
521
+ },
522
+ stopKillSuggestions: function () {
523
+ window.clearInterval( this.intervalId );
524
+ },
525
+ isCursorAtEnd: function () {
526
+ var that = this,
527
+ valLength = that.el.val().length,
528
+ selectionStart = that.element.selectionStart,
529
+ range;
530
+
531
+ if ( typeof selectionStart === 'number' ) {
532
+ return selectionStart === valLength;
533
+ }
534
+ if ( document.selection ) {
535
+ range = document.selection.createRange();
536
+ range.moveStart( 'character', -valLength );
537
+ return valLength === range.text.length;
538
+ }
539
+ return true;
540
+ },
541
+ onKeyPress: function ( e ) {
542
+ var that = this;
543
+
544
+ // If suggestions are hidden and user presses arrow down, display suggestions:
545
+ if ( !that.disabled && !that.visible && e.which === keys.DOWN && that.currentValue ) {
546
+ that.suggest();
547
+ return;
548
+ }
549
+
550
+ if ( that.disabled || !that.visible ) {
551
+ return;
552
+ }
553
+
554
+ switch ( e.which ) {
555
+ case keys.ESC:
556
+ that.el.val( that.currentValue );
557
+ that.hide();
558
+ break;
559
+ case keys.RIGHT:
560
+ if ( that.hint && that.options.onHint && that.isCursorAtEnd() ) {
561
+ that.selectHint();
562
+ break;
563
+ }
564
+ return;
565
+ case keys.TAB:
566
+ if ( that.hint && that.options.onHint ) {
567
+ that.selectHint();
568
+ return;
569
+ }
570
+ if ( that.selectedIndex === -1 ) {
571
+ that.hide();
572
+ return;
573
+ }
574
+ that.select( that.selectedIndex );
575
+ if ( that.options.tabDisabled === false ) {
576
+ return;
577
+ }
578
+ break;
579
+ case keys.RETURN:
580
+ if ( that.selectedIndex === -1 ) {
581
+ that.hide();
582
+ return;
583
+ }
584
+ that.select( that.selectedIndex );
585
+ break;
586
+ case keys.UP:
587
+ that.moveUp();
588
+ break;
589
+ case keys.DOWN:
590
+ that.moveDown();
591
+ break;
592
+ default:
593
+ return;
594
+ }
595
+
596
+ // Cancel event if function did not return:
597
+ e.stopImmediatePropagation();
598
+ e.preventDefault();
599
+ },
600
+ onKeyUp: function ( e ) {
601
+ var that = this;
602
+
603
+ if ( that.disabled ) {
604
+ return;
605
+ }
606
+
607
+ switch ( e.which ) {
608
+ case keys.UP:
609
+ case keys.DOWN:
610
+ return;
611
+ }
612
+
613
+ clearInterval( that.onChangeInterval );
614
+
615
+ if ( that.currentValue !== that.el.val() ) {
616
+ that.findBestHint();
617
+ if ( that.options.deferRequestBy > 0 ) {
618
+ // Defer lookup in case when value changes very quickly:
619
+ that.onChangeInterval = setInterval( function () {
620
+ that.onValueChange();
621
+ }, that.options.deferRequestBy );
622
+ } else {
623
+ that.onValueChange();
624
+ }
625
+ }
626
+ },
627
+ onValueChange: function () {
628
+ var that = this,
629
+ options = that.options,
630
+ value = that.el.val(),
631
+ query = that.getQuery( value );
632
+
633
+ if ( that.selection && that.currentValue !== query ) {
634
+ that.selection = null;
635
+ ( options.onInvalidateSelection || $.noop ).call( that.element );
636
+ }
637
+
638
+ clearInterval( that.onChangeInterval );
639
+ that.currentValue = value;
640
+ that.selectedIndex = -1;
641
+
642
+ // Check existing suggestion for the match before proceeding:
643
+ if ( options.triggerSelectOnValidInput && that.isExactMatch( query ) ) {
644
+ that.select( 0 );
645
+ return;
646
+ }
647
+
648
+ if ( query.length < options.minChars ) {
649
+ $( '.' + that.options.closeTrigger ).removeClass( that.options.closeTrigger );
650
+ that.hide();
651
+ } else {
652
+ that.getSuggestions( query );
653
+ }
654
+ },
655
+ isExactMatch: function ( query ) {
656
+ var suggestions = this.suggestions;
657
+
658
+ return ( suggestions.length === 1 && suggestions[0].value.toLowerCase() === query.toLowerCase() );
659
+ },
660
+ getQuery: function ( value ) {
661
+ var delimiter = this.options.delimiter,
662
+ parts;
663
+
664
+ if ( !delimiter ) {
665
+ return value;
666
+ }
667
+ parts = value.split( delimiter );
668
+ return $.trim( parts[parts.length - 1] );
669
+ },
670
+ getSuggestionsLocal: function ( query ) {
671
+ var that = this,
672
+ options = that.options,
673
+ queryLowerCase = query.toLowerCase(),
674
+ filter = options.lookupFilter,
675
+ limit = parseInt( options.lookupLimit, 10 ),
676
+ data;
677
+
678
+ data = {
679
+ suggestions: $.grep( options.lookup, function ( suggestion ) {
680
+ return filter( suggestion, query, queryLowerCase );
681
+ } )
682
+ };
683
+
684
+ if ( limit && data.suggestions.length > limit ) {
685
+ data.suggestions = data.suggestions.slice( 0, limit );
686
+ }
687
+
688
+ return data;
689
+ },
690
+ getSuggestions: function ( q ) {
691
+ var response,
692
+ that = this,
693
+ options = that.options,
694
+ serviceUrl = options.serviceUrl,
695
+ params,
696
+ cacheKey,
697
+ ajaxSettings;
698
+
699
+ options.params[options.paramName] = q;
700
+ params = options.ignoreParams ? null : options.params;
701
+
702
+ that.preloader( 'show', $( '.' + options.preloaderClass ), 'dgwt-wcas-inner-preloader', dgwt_wcas.preloader_url, true );
703
+
704
+ if ( options.onSearchStart.call( that.element, options.params ) === false ) {
705
+ return;
706
+ }
707
+
708
+ if ( $.isFunction( options.lookup ) ) {
709
+ options.lookup( q, function ( data ) {
710
+ that.suggestions = data.suggestions;
711
+ that.suggest();
712
+ that.getDetails( data.suggestions[0] );
713
+ options.onSearchComplete.call( that.element, q, data.suggestions );
714
+ } );
715
+ return;
716
+ }
717
+
718
+ if ( that.isLocal ) {
719
+ response = that.getSuggestionsLocal( q );
720
+ } else {
721
+ if ( $.isFunction( serviceUrl ) ) {
722
+ serviceUrl = serviceUrl.call( that.element, q );
723
+ }
724
+ cacheKey = serviceUrl + '?' + $.param( params || { } );
725
+ response = that.cachedResponse[cacheKey];
726
+ }
727
+
728
+ if ( response && $.isArray( response.suggestions ) ) {
729
+ that.suggestions = response.suggestions;
730
+ that.suggest();
731
+ that.getDetails( response.suggestions[0] );
732
+ options.onSearchComplete.call( that.element, q, response.suggestions );
733
+ } else if ( !that.isBadQuery( q ) ) {
734
+ that.abortAjax();
735
+
736
+ ajaxSettings = {
737
+ url: serviceUrl,
738
+ data: params,
739
+ type: options.type,
740
+ dataType: options.dataType
741
+ };
742
+
743
+ $.extend( ajaxSettings, options.ajaxSettings );
744
+
745
+ that.currentRequest = $.ajax( ajaxSettings ).done( function ( data ) {
746
+ var result;
747
+ that.currentRequest = null;
748
+ result = options.transformResult( data, q );
749
+
750
+ if ( typeof result.suggestions !== 'undefined' ) {
751
+ that.processResponse( result, q, cacheKey );
752
+ that.getDetails( result.suggestions[0] );
753
+ }
754
+ options.onSearchComplete.call( that.element, q, result.suggestions );
755
+ } ).fail( function ( jqXHR, textStatus, errorThrown ) {
756
+ options.onSearchError.call( that.element, q, jqXHR, textStatus, errorThrown );
757
+ } );
758
+ } else {
759
+ options.onSearchComplete.call( that.element, q, [ ] );
760
+ }
761
+
762
+ },
763
+ getDetails: function ( suggestion ) {
764
+
765
+ var that = this,
766
+ options = that.options;
767
+
768
+ // Disable details panel
769
+ if ( options.showDetailsPanel != true || $( window ).width() < 992 || ( 'ontouchend' in document ) ) {
770
+ return false;
771
+ }
772
+ ;
773
+
774
+ // Brake if there are no suggestions
775
+ if ( suggestion == null ) {
776
+ return;
777
+ }
778
+
779
+ var cacheKey,
780
+ containerDetails = $( '.' + options.containerDetailsClass ),
781
+ result;
782
+
783
+ that.fixHeight();
784
+
785
+ var data = {
786
+ action: dgwt_wcas.action_result_details,
787
+ post_id: suggestion.post_id != null ? suggestion.post_id : 0,
788
+ term_id: suggestion.term_id != null ? suggestion.term_id : 0,
789
+ taxonomy: suggestion.taxonomy != null ? suggestion.taxonomy : '',
790
+ value: suggestion.value != null ? suggestion.value : '',
791
+ };
792
+
793
+ // Add to cache
794
+ cacheKey = data.action + data.post_id + data.term_id + data.taxonomy;
795
+ result = that.cachedDetails[cacheKey];
796
+
797
+ if ( result != null ) {
798
+
799
+ // Load response from cache
800
+ containerDetails.html( result.details );
801
+ that.fixHeight();
802
+ that.fixPositionDetailsBox();
803
+
804
+ } else {
805
+
806
+ containerDetails.html( '' );
807
+ that.preloader( 'show', containerDetails, '', dgwt_wcas.preloader_url );
808
+
809
+ $.ajax( {
810
+ data: data,
811
+ type: 'post',
812
+ url: dgwt_wcas.ajax_details_endpoint,
813
+ success: function ( response ) {
814
+
815
+ var result = typeof response === 'string' ? jQuery.parseJSON( response ) : response;
816
+
817
+ // Cached response
818
+ that.cachedDetails[cacheKey] = result;
819
+
820
+ that.preloader( 'hide', containerDetails, '', dgwt_wcas.preloader_url );
821
+
822
+ if ( result.details != null ) {
823
+ containerDetails.html( result.details );
824
+ } else {
825
+
826
+ containerDetails.html( '@TODO BŁĄD' );
827
+ }
828
+ that.fixPositionDetailsBox();
829
+ that.fixHeight();
830
+ },
831
+ error: function ( jqXHR, exception ) {
832
+
833
+ that.preloader( 'hide', containerDetails, '', dgwt_wcas.preloader_url );
834
+
835
+ containerDetails.html( jqXHR );
836
+ that.fixPositionDetailsBox();
837
+ that.fixHeight();
838
+ },
839
+ } );
840
+ }
841
+ },
842
+ isBadQuery: function ( q ) {
843
+ if ( !this.options.preventBadQueries ) {
844
+ return false;
845
+ }
846
+
847
+ var badQueries = this.badQueries,
848
+ i = badQueries.length;
849
+
850
+ while ( i-- ) {
851
+ if ( q.indexOf( badQueries[i] ) === 0 ) {
852
+ return true;
853
+ }
854
+ }
855
+
856
+ return false;
857
+ },
858
+ hide: function () {
859
+ var that = this,
860
+ container = $( that.suggestionsContainer ),
861
+ containerDetails = $( that.detailsContainer );
862
+
863
+ if ( $.isFunction( that.options.onHide ) && that.visible ) {
864
+ that.options.onHide.call( that.element, container );
865
+ }
866
+
867
+ that.visible = false;
868
+ that.selectedIndex = -1;
869
+ clearInterval( that.onChangeInterval );
870
+ $( that.suggestionsContainer ).hide();
871
+ $( that.detailsContainer ).hide();
872
+ that.signalHint( null );
873
+ },
874
+ suggest: function () {
875
+ if ( this.suggestions.length === 0 ) {
876
+ if ( this.options.showNoSuggestionNotice ) {
877
+ this.noSuggestions();
878
+ } else {
879
+ this.hide();
880
+ }
881
+ return;
882
+ }
883
+
884
+ var that = this,
885
+ options = that.options,
886
+ groupBy = options.groupBy,
887
+ formatResult = options.formatResult,
888
+ value = that.getQuery( that.currentValue ),
889
+ className = that.classes.suggestion,
890
+ classSelected = that.classes.selected,
891
+ container = $( that.suggestionsContainer ),
892
+ containerDetails = $( that.detailsContainer ),
893
+ noSuggestionsContainer = $( that.noSuggestionsContainer ),
894
+ beforeRender = options.beforeRender,
895
+ html = '',
896
+ category,
897
+ formatGroup = function ( suggestion, index ) {
898
+ var currentCategory = suggestion.data[groupBy];
899
+
900
+ if ( category === currentCategory ) {
901
+ return '';
902
+ }
903
+
904
+ category = currentCategory;
905
+
906
+ return '<div class="autocomplete-group"><strong>' + category + '</strong></div>';
907
+ };
908
+
909
+ if ( options.triggerSelectOnValidInput && that.isExactMatch( value ) ) {
910
+ that.select( 0 );
911
+ return;
912
+ }
913
+
914
+ // Build suggestions inner HTML:
915
+ $.each( that.suggestions, function ( i, suggestion ) {
916
+
917
+ var parent = '',
918
+ dataAttrs = '',
919
+ is_img = false;
920
+
921
+ if ( groupBy ) {
922
+ html += formatGroup( suggestion, value, i );
923
+ }
924
+
925
+ if ( typeof suggestion.parents != 'undefined' ) {
926
+ parent = suggestion.parents;
927
+ }
928
+
929
+ // Image
930
+ if ( options.showImage === true && typeof suggestion.thumb_html != 'undefined' ) {
931
+ is_img = true;
932
+ }
933
+
934
+ // One suggestion HTML
935
+ dataAttrs += typeof suggestion.post_id != 'undefined' ? 'data-post-id="' + suggestion.post_id + '" ' : '';
936
+ dataAttrs += typeof suggestion.taxonomy != 'undefined' ? 'data-taxonomy="' + suggestion.taxonomy + '" ' : '';
937
+ dataAttrs += typeof suggestion.term_id != 'undefined' ? 'data-term-id="' + suggestion.term_id + '" ' : '';
938
+ html += '<div class="' + className + '" data-index="' + i + '" ' + dataAttrs + '>';
939
+
940
+ // Image
941
+ if ( is_img ) {
942
+ html += '<span class="dgwt-wcas-si">' + suggestion.thumb_html + '</span>';
943
+ }
944
+
945
+
946
+ html += is_img ? '<div class="dgwt-wcas-content-wrapp">' : '';
947
+
948
+
949
+ // Title
950
+ html += '<span class="dgwt-wcas-st">' + formatResult( suggestion, value ) + parent + '</span>';
951
+
952
+ // Price
953
+ if ( options.showPrice === true && typeof suggestion.price != 'undefined' ) {
954
+ html += '<span class="dgwt-wcas-sp">' + suggestion.price + '</span>';
955
+ }
956
+
957
+ // Description
958
+ if ( options.showDescription === true && typeof suggestion.desc != 'undefined' ) {
959
+ html += '<span class="dgwt-wcas-sd">' + suggestion.desc + '</span>';
960
+ }
961
+
962
+ // On sale product badge
963
+ if ( options.showFeaturedBadge === true && suggestion.on_sale === true ) {
964
+ html += '<span class="dgwt-wcas-badge dgwt-wcas-badge-os">' + options.saleBadgeText + '</span>';
965
+ }
966
+
967
+ // Featured product badge
968
+ if ( options.showFeaturedBadge === true && suggestion.featured === true ) {
969
+ html += '<span class="dgwt-wcas-badge dgwt-wcas-badge-f">' + options.featuredBadgeText + '</span>';
970
+ }
971
+
972
+
973
+ html += is_img ? '</div>' : '';
974
+ html += '</div>';
975
+ } );
976
+
977
+ this.adjustContainerWidth();
978
+
979
+ noSuggestionsContainer.detach();
980
+ container.html( html );
981
+
982
+ if ( $.isFunction( beforeRender ) ) {
983
+ beforeRender.call( that.element, container );
984
+ }
985
+
986
+ that.fixPosition();
987
+ container.show();
988
+
989
+ // Add class on show
990
+ container.parent().addClass( 'dgwt-wcas-open' );
991
+
992
+ if ( options.showDetailsPanel === true ) {
993
+ containerDetails.show();
994
+ }
995
+
996
+ // Select first value by default:
997
+ if ( options.autoSelectFirst ) {
998
+ that.selectedIndex = 0;
999
+ container.scrollTop( 0 );
1000
+ container.children( '.' + className ).first().addClass( classSelected );
1001
+ }
1002
+
1003
+ that.visible = true;
1004
+ that.findBestHint();
1005
+ },
1006
+ noSuggestions: function () {
1007
+ var that = this,
1008
+ container = $( that.suggestionsContainer ),
1009
+ noSuggestionsContainer = $( that.noSuggestionsContainer );
1010
+
1011
+ this.adjustContainerWidth();
1012
+
1013
+ // Some explicit steps. Be careful here as it easy to get
1014
+ // noSuggestionsContainer removed from DOM if not detached properly.
1015
+ noSuggestionsContainer.detach();
1016
+ container.empty(); // clean suggestions if any
1017
+ container.append( noSuggestionsContainer );
1018
+
1019
+ that.fixPosition();
1020
+
1021
+ container.show();
1022
+ that.visible = true;
1023
+ },
1024
+ adjustContainerWidth: function () {
1025
+ var that = this,
1026
+ options = that.options,
1027
+ width,
1028
+ container = $( that.suggestionsContainer ).parent(),
1029
+ containerSugg = $( that.suggestionsContainer ),
1030
+ containerDetails = $( that.detailsContainer ),
1031
+ maxWidth = 550;
1032
+
1033
+ // If width is auto, adjust width before displaying suggestions,
1034
+ if ( options.width === 'auto' ) {
1035
+ width = that.el.outerWidth();
1036
+ containerSugg.css( 'width', width + 'px' );
1037
+ }
1038
+
1039
+
1040
+ // Set specific style on the bigger search form
1041
+ if ( container.width() >= maxWidth && options.showDetailsPanel === true ) {
1042
+
1043
+ container.addClass( 'dgwt-wcas-full-width' );
1044
+
1045
+ containerSugg.outerWidth( 300 );
1046
+ containerDetails.innerWidth( container.width() - 300 );
1047
+
1048
+ container.removeClass( 'dgwt-wcas-details-left' );
1049
+ container.removeClass( 'dgwt-wcas-details-right' );
1050
+
1051
+ if ( options.is_rtl === true ) {
1052
+
1053
+ containerDetails.css( 'left', '0' );
1054
+ containerSugg.css( 'right', '0' );
1055
+ } else {
1056
+
1057
+ containerDetails.css( 'right', '0' );
1058
+ containerSugg.css( 'left', '0' );
1059
+ }
1060
+
1061
+
1062
+ return;
1063
+ }
1064
+
1065
+ if ( options.cointainerDetailsPos === 'left' ) {
1066
+ containerDetails.parent().addClass( 'dgwt-wcas-details-left' );
1067
+ containerDetails.css( 'left', '-' + containerDetails.outerWidth() + 'px' );
1068
+
1069
+ } else {
1070
+ containerDetails.parent().addClass( 'dgwt-wcas-details-right' );
1071
+ containerDetails.css( 'left', container.outerWidth() + 'px' );
1072
+ }
1073
+
1074
+ },
1075
+ findBestHint: function () {
1076
+ var that = this,
1077
+ value = that.el.val().toLowerCase(),
1078
+ bestMatch = null;
1079
+
1080
+ if ( !value ) {
1081
+ return;
1082
+ }
1083
+
1084
+ $.each( that.suggestions, function ( i, suggestion ) {
1085
+ var foundMatch = suggestion.value.toLowerCase().indexOf( value ) === 0;
1086
+ if ( foundMatch ) {
1087
+ bestMatch = suggestion;
1088
+ }
1089
+ return !foundMatch;
1090
+ } );
1091
+
1092
+ that.signalHint( bestMatch );
1093
+ },
1094
+ signalHint: function ( suggestion ) {
1095
+ var hintValue = '',
1096
+ that = this;
1097
+ if ( suggestion ) {
1098
+ hintValue = that.currentValue + suggestion.value.substr( that.currentValue.length );
1099
+ }
1100
+ if ( that.hintValue !== hintValue ) {
1101
+ that.hintValue = hintValue;
1102
+ that.hint = suggestion;
1103
+ ( this.options.onHint || $.noop )( hintValue );
1104
+ }
1105
+ },
1106
+ /*
1107
+ * Manages preloader
1108
+ *
1109
+ * @param action (show or hide)
1110
+ * @param container (parent selector)
1111
+ * @param cssClass
1112
+ * @param customImage absolyt path to te prelader custom image
1113
+ * @param viaClass bool
1114
+ */
1115
+ preloader: function ( action, container, cssClass, customImage, viaClass ) {
1116
+
1117
+ var html,
1118
+ defaultClass = 'dgwt-wcas-preloader-wrapp',
1119
+ cssClasses = cssClass == null ? defaultClass : defaultClass + ' ' + cssClass;
1120
+
1121
+ // Disable preloader and check if container exist
1122
+
1123
+ if ( dgwt_wcas.show_preloader != 1 || container.length == 0 ) {
1124
+ return;
1125
+ }
1126
+
1127
+ if ( customImage == '' && viaClass === true ) {
1128
+ if ( action === 'hide' ) {
1129
+ container.removeClass( cssClass );
1130
+ } else {
1131
+ container.addClass( cssClass );
1132
+ }
1133
+ return;
1134
+ }
1135
+
1136
+ // Action hide
1137
+ if ( action === 'hide' ) {
1138
+ $( defaultClass ).remove();
1139
+ return
1140
+ }
1141
+
1142
+ // Action show
1143
+ if ( action === 'show' ) {
1144
+ if ( customImage != '' ) {
1145
+ html = '<div class="' + cssClasses + '"><img src="' + customImage + '" /></div>';
1146
+ } else {
1147
+ html = '<div class="' + cssClasses + '"><div class="dgwt-wcas-default-preloader"></div></div>';
1148
+ }
1149
+
1150
+ container.html( html );
1151
+ }
1152
+ },
1153
+ verifySuggestionsFormat: function ( suggestions ) {
1154
+
1155
+ // If suggestions is string array, convert them to supported format:
1156
+ if ( suggestions.length && typeof suggestions[0] === 'string' ) {
1157
+ return $.map( suggestions, function ( value ) {
1158
+ return { value: value, data: null };
1159
+ } );
1160
+ }
1161
+
1162
+ return suggestions;
1163
+ },
1164
+ validateOrientation: function ( orientation, fallback ) {
1165
+ orientation = $.trim( orientation || '' ).toLowerCase();
1166
+
1167
+ if ( $.inArray( orientation, [ 'auto', 'bottom', 'top' ] ) === -1 ) {
1168
+ orientation = fallback;
1169
+ }
1170
+
1171
+ return orientation;
1172
+ },
1173
+ processResponse: function ( result, originalQuery, cacheKey ) {
1174
+ var that = this,
1175
+ options = that.options;
1176
+
1177
+ result.suggestions = that.verifySuggestionsFormat( result.suggestions );
1178
+
1179
+ // Cache results if cache is not disabled:
1180
+ if ( !options.noCache ) {
1181
+ that.cachedResponse[cacheKey] = result;
1182
+ if ( options.preventBadQueries && result.suggestions.length === 0 ) {
1183
+ that.badQueries.push( originalQuery );
1184
+ }
1185
+ }
1186
+
1187
+ // Return if originalQuery is not matching current query:
1188
+ if ( originalQuery !== that.getQuery( that.currentValue ) ) {
1189
+ return;
1190
+ }
1191
+
1192
+ that.suggestions = result.suggestions;
1193
+ that.suggest();
1194
+ },
1195
+ activate: function ( index ) {
1196
+ var that = this,
1197
+ activeItem,
1198
+ selected = that.classes.selected,
1199
+ container = $( that.suggestionsContainer ),
1200
+ children = container.find( '.' + that.classes.suggestion );
1201
+
1202
+ container.find( '.' + selected ).removeClass( selected );
1203
+
1204
+ that.selectedIndex = index;
1205
+
1206
+ if ( that.selectedIndex !== -1 && children.length > that.selectedIndex ) {
1207
+ activeItem = children.get( that.selectedIndex );
1208
+ $( activeItem ).addClass( selected );
1209
+ return activeItem;
1210
+ }
1211
+
1212
+ return null;
1213
+ },
1214
+ selectHint: function () {
1215
+ var that = this,
1216
+ i = $.inArray( that.hint, that.suggestions );
1217
+
1218
+ that.select( i );
1219
+ },
1220
+ select: function ( i ) {
1221
+ var that = this;
1222
+ that.hide();
1223
+ that.onSelect( i );
1224
+ },
1225
+ moveUp: function () {
1226
+ var that = this;
1227
+
1228
+ if ( that.selectedIndex === -1 ) {
1229
+ return;
1230
+ }
1231
+
1232
+ if ( that.selectedIndex === 0 ) {
1233
+ $( that.suggestionsContainer ).children().first().removeClass( that.classes.selected );
1234
+ that.selectedIndex = -1;
1235
+ that.el.val( that.currentValue );
1236
+ that.findBestHint();
1237
+ return;
1238
+ }
1239
+
1240
+ that.adjustScroll( that.selectedIndex - 1 );
1241
+ },
1242
+ moveDown: function () {
1243
+ var that = this;
1244
+
1245
+ if ( that.selectedIndex === ( that.suggestions.length - 1 ) ) {
1246
+ return;
1247
+ }
1248
+
1249
+ that.adjustScroll( that.selectedIndex + 1 );
1250
+ },
1251
+ adjustScroll: function ( index ) {
1252
+ var that = this,
1253
+ activeItem = that.activate( index );
1254
+
1255
+ if ( !activeItem ) {
1256
+ return;
1257
+ }
1258
+
1259
+ var offsetTop,
1260
+ upperBound,
1261
+ lowerBound,
1262
+ heightDelta = $( activeItem ).outerHeight();
1263
+
1264
+ offsetTop = activeItem.offsetTop;
1265
+ upperBound = $( that.suggestionsContainer ).scrollTop();
1266
+ lowerBound = upperBound + that.options.maxHeight - heightDelta;
1267
+
1268
+ if ( offsetTop < upperBound ) {
1269
+ $( that.suggestionsContainer ).scrollTop( offsetTop );
1270
+ } else if ( offsetTop > lowerBound ) {
1271
+ $( that.suggestionsContainer ).scrollTop( offsetTop - that.options.maxHeight + heightDelta );
1272
+ }
1273
+
1274
+ if ( !that.options.preserveInput ) {
1275
+ that.el.val( that.getValue( that.suggestions[index].value ) );
1276
+ }
1277
+ that.signalHint( null );
1278
+ },
1279
+ onSelect: function ( index ) {
1280
+ var that = this,
1281
+ onSelectCallback = that.options.onSelect,
1282
+ suggestion = that.suggestions[index];
1283
+
1284
+ that.currentValue = that.getValue( suggestion.value );
1285
+
1286
+ if ( that.currentValue !== that.el.val() && !that.options.preserveInput ) {
1287
+ that.el.val( that.currentValue );
1288
+ }
1289
+
1290
+ if ( suggestion.id != -1 ) {
1291
+ window.location.href = suggestion.url;
1292
+ }
1293
+
1294
+ that.signalHint( null );
1295
+ that.suggestions = [ ];
1296
+ that.selection = suggestion;
1297
+ if ( $.isFunction( onSelectCallback ) ) {
1298
+ onSelectCallback.call( that.element, suggestion );
1299
+ }
1300
+ },
1301
+ onMouseOver: function ( index ) {
1302
+ var that = this,
1303
+ onMouseOverCallback = that.options.onMouseOver,
1304
+ suggestion = that.suggestions[index];
1305
+ that.getDetails( suggestion );
1306
+ if ( $.isFunction( onMouseOverCallback ) ) {
1307
+ onMouseOverCallback.call( that.element, suggestion );
1308
+ }
1309
+ },
1310
+ onMouseLeave: function ( index ) {
1311
+ var that = this,
1312
+ onMouseLeaveCallback = that.options.onMouseLeave,
1313
+ suggestion = that.suggestions[index];
1314
+
1315
+ if ( $.isFunction( onMouseLeaveCallback ) ) {
1316
+ onMouseLeaveCallback.call( that.element, suggestion );
1317
+ }
1318
+ },
1319
+ getValue: function ( value ) {
1320
+ var that = this,
1321
+ delimiter = that.options.delimiter,
1322
+ currentValue,
1323
+ parts;
1324
+
1325
+ if ( !delimiter ) {
1326
+ return value;
1327
+ }
1328
+
1329
+ currentValue = that.currentValue;
1330
+ parts = currentValue.split( delimiter );
1331
+
1332
+ if ( parts.length === 1 ) {
1333
+ return value;
1334
+ }
1335
+
1336
+ return currentValue.substr( 0, currentValue.length - parts[parts.length - 1].length ) + value;
1337
+ },
1338
+ dispose: function () {
1339
+ var that = this;
1340
+ that.el.off( '.autocomplete' ).removeData( 'autocomplete' );
1341
+ that.disableKillerFn();
1342
+ $( window ).off( 'resize.autocomplete', that.fixPositionCapture );
1343
+ $( that.suggestionsContainer ).remove();
1344
+ }
1345
+ };
1346
+
1347
+
1348
+
1349
+
1350
+ // Create chainable jQuery plugin:
1351
+ $.fn.dgwtWcasAutocomplete = function ( options, args ) {
1352
+ var dataKey = 'autocomplete';
1353
+ // If function invoked without argument return
1354
+ // instance of the first matched element:
1355
+ if ( arguments.length === 0 ) {
1356
+ return this.first().data( dataKey );
1357
+ }
1358
+
1359
+ return this.each( function () {
1360
+ var inputElement = $( this ),
1361
+ instance = inputElement.data( dataKey );
1362
+
1363
+ if ( typeof options === 'string' ) {
1364
+ if ( instance && typeof instance[options] === 'function' ) {
1365
+ instance[options]( args );
1366
+ }
1367
+ } else {
1368
+ // If instance already exists, destroy it:
1369
+ if ( instance && instance.dispose ) {
1370
+ instance.dispose();
1371
+ }
1372
+ instance = new Autocomplete( this, options );
1373
+ inputElement.data( dataKey, instance );
1374
+ }
1375
+ } );
1376
+ };
1377
+
1378
+
1379
+
1380
+ ( function () {
1381
+
1382
+ // RUN
1383
+ $( document ).ready( function () {
1384
+ "use strict";
1385
+
1386
+ /*-----------------------------------------------------------------
1387
+ /* Positioning search preloader
1388
+ /*------------ -----------------------------------------------------*/
1389
+ if ( $( '.dgwt-wcas-search-submit' ).length > 0 ) {
1390
+ $( '.dgwt-wcas-preloader' ).css( 'right', $( '.dgwt-wcas-search-submit' ).outerWidth() + 'px' );
1391
+ }
1392
+
1393
+ /*-----------------------------------------------------------------
1394
+ /* Fire autocomplete
1395
+ /*------------ -----------------------------------------------------*/
1396
+ var showDetailsPanel = dgwt_wcas.show_details_box == 1 ? true : false;
1397
+
1398
+ // Disable details panel on small screens
1399
+ if ( jQuery( window ).width() < 992 || ( 'ontouchend' in document ) ) {
1400
+ showDetailsPanel = false;
1401
+ }
1402
+
1403
+ $( '.dgwt-wcas-search-input' ).dgwtWcasAutocomplete( {
1404
+ minChars: dgwt_wcas.min_chars,
1405
+ autoSelectFirst: true,
1406
+ triggerSelectOnValidInput: false,
1407
+ serviceUrl: dgwt_wcas.ajax_search_endpoint,
1408
+ paramName: 'dgwt_wcas_keyword',
1409
+ showDetailsPanel: showDetailsPanel,
1410
+ showImage: dgwt_wcas.show_images == 1 ? true : false,
1411
+ showPrice: dgwt_wcas.show_price == 1 ? true : false,
1412
+ showDescription: dgwt_wcas.show_desc == 1 ? true : false,
1413
+ showSaleBadge: dgwt_wcas.show_sale_badge == 1 ? true : false,
1414
+ showFeaturedBadge: dgwt_wcas.show_featured_badge == 1 ? true : false,
1415
+ saleBadgeText: dgwt_wcas.t.sale_badge,
1416
+ featuredBadgeText: dgwt_wcas.t.featured_badge,
1417
+ cointainerDetailsPos: dgwt_wcas.details_box_pos,
1418
+ is_rtl: dgwt_wcas.is_rtl == 1 ? true : false
1419
+ } );
1420
+
1421
+ } );
1422
+
1423
+ }() );
1424
+
1425
+ } ) );
assets/js/jquery.dgwt-wcas.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports&&"function"==typeof require?require("jquery"):jQuery)}(function(e){"use strict";function t(s,n){var i=function(){},o=this,a={ajaxSettings:{},autoSelectFirst:!1,appendTo:document.body,serviceUrl:null,lookup:null,onSelect:null,onMouseOver:null,onMouseLeave:null,width:"auto",containerDetailsWidth:"auto",showDetailsPanel:!1,showImage:!1,showPrice:!1,showDescription:!1,showSaleBadge:!1,showFeaturedBadge:!1,saleBadgeText:"sale",featuredBadgeText:"featured",minChars:1,maxHeight:1e3,deferRequestBy:0,params:{},formatResult:t.formatResult,delimiter:null,zIndex:9999,type:"GET",noCache:!1,is_rtl:!1,onSearchStart:i,onSearchComplete:i,onSearchError:i,preserveInput:!1,wrapperaClass:"dgwt-wcas-search-wrapp",containerClass:"dgwt-wcas-suggestions-wrapp",containerDetailsClass:"dgwt-wcas-details-wrapp",cointainerDetailsPos:"right",preloaderClass:"dgwt-wcas-preloader",closeTrigger:"dgwt-wcas-close",tabDisabled:!1,dataType:"text",currentRequest:null,triggerSelectOnValidInput:!0,preventBadQueries:!0,lookupFilter:function(e,t,s){return-1!==e.value.toLowerCase().indexOf(s)},paramName:"query",transformResult:function(t){return"string"==typeof t?e.parseJSON(t):t},showNoSuggestionNotice:!1,noSuggestionNotice:"No results",orientation:"bottom",forceFixPosition:!1};o.element=s,o.el=e(s),o.suggestions=[],o.badQueries=[],o.selectedIndex=-1,o.currentValue=o.element.value,o.intervalId=0,o.cachedResponse={},o.cachedDetails={},o.onChangeInterval=null,o.onChange=null,o.isLocal=!1,o.suggestionsContainer=null,o.detailsContainer=null,o.noSuggestionsContainer=null,o.options=e.extend({},a,n),o.classes={selected:"dgwt-wcas-suggestion-selected",suggestion:"dgwt-wcas-suggestion"},o.hint=null,o.hintValue="",o.selection=null,o.initialize(),o.setOptions(n)}var s=function(){return{escapeRegExChars:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},createNode:function(e){var t=document.createElement("div");return t.className=e,t.style.position="absolute",t.style.display="none",t}}}(),n={ESC:27,TAB:9,RETURN:13,LEFT:37,UP:38,RIGHT:39,DOWN:40};t.utils=s,e.Autocomplete=t,t.formatResult=function(e,t){var n="("+s.escapeRegExChars(t)+")";return e.value.replace(new RegExp(n,"gi"),"<strong>$1</strong>").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/&lt;(\/?strong)&gt;/g,"<$1>")},t.prototype={killerFn:null,initialize:function(){var s,n,i=this,o="."+i.classes.suggestion,a=(i.classes.selected,i.options),l="."+a.closeTrigger;i.element.setAttribute("autocomplete","off"),i.killerFn=function(t){0===e(t.target).closest("."+i.options.containerClass).length&&0===e(t.target).closest("."+i.options.containerDetailsClass).length&&(i.killSuggestions(),i.disableKillerFn())},i.noSuggestionsContainer=e('<div class="dgwt-wcas-no-suggestion"></div>').html(this.options.noSuggestionNotice).get(0),i.suggestionsContainer=t.utils.createNode(a.containerClass),s=e(i.suggestionsContainer),s.appendTo(i.el.closest("."+a.wrapperaClass)),a.showImage===!0&&s.addClass("dgwt-wcas-has-img"),a.showPrice===!0&&s.addClass("dgwt-wcas-has-price"),a.showDescription===!0&&s.addClass("dgwt-wcas-has-desc"),"auto"!==a.width&&s.width(a.width),a.showDetailsPanel===!0&&(i.detailsContainer=t.utils.createNode(a.containerDetailsClass),n=e(i.detailsContainer),n.appendTo(i.el.closest("."+a.wrapperaClass))),s.on("mouseover.autocomplete",o,function(){i.onMouseOver(e(this).data("index")),i.activate(e(this).data("index"))}),s.on("mouseout.autocomplete",function(){}),e(document).on("click.autocomplete",l,function(t){i.killerFn(t),i.clear(t),e(this).removeClass(a.closeTrigger),i.el.val("").focus()}),s.on("click.autocomplete",o,function(){i.select(e(this).data("index"))}),i.fixPositionCapture=function(){i.visible&&i.fixPosition()},e(window).on("resize.autocomplete",i.fixPositionCapture),i.el.on("keydown.autocomplete",function(e){i.onKeyPress(e)}),i.el.on("keyup.autocomplete",function(e){i.onKeyUp(e)}),i.el.on("blur.autocomplete",function(){i.onBlur()}),i.el.on("focus.autocomplete",function(){i.onFocus()}),i.el.on("change.autocomplete",function(e){i.onKeyUp(e)}),i.el.on("input.autocomplete",function(e){i.onKeyUp(e)})},onFocus:function(){var e=this;e.fixPosition(),0===e.options.minChars&&0===e.el.val().length&&e.onValueChange()},onBlur:function(){this.enableKillerFn()},abortAjax:function(){var e=this;e.currentRequest&&(e.currentRequest.abort(),e.currentRequest=null)},setOptions:function(t){var s=this,n=s.options;e.extend(n,t),s.isLocal=e.isArray(n.lookup),s.isLocal&&(n.lookup=s.verifySuggestionsFormat(n.lookup)),n.orientation=s.validateOrientation(n.orientation,"bottom"),e(s.suggestionsContainer).css({"max-height":n.maxHeight+"px",width:n.width+"px","z-index":n.zIndex}),n.showDetailsPanel===!0&&jQuery(s.suggestionsContainer).parent().addClass("dgwt-wcas-is-details"),s.options.onSearchComplete=function(){s.preloader("hide",e("."+n.preloaderClass),"dgwt-wcas-inner-preloader",dgwt_wcas.preloader_url,!0),s.preloader("show",e("."+n.preloaderClass),n.closeTrigger,"",!0)}},clearCache:function(){this.cachedResponse={},this.cachedDetails={},this.badQueries=[]},clear:function(){this.clearCache(),this.currentValue="",this.suggestions=[]},disable:function(){var e=this;e.disabled=!0,clearInterval(e.onChangeInterval),e.abortAjax()},enable:function(){this.disabled=!1},fixPosition:function(){var t=this,s=(t.options,e(t.suggestionsContainer)),n=(e(t.detailsContainer),s.parent().get(0));if(n===document.body||t.options.forceFixPosition){var i=t.options.orientation,o=s.outerHeight(),a=t.el.outerHeight(),l=t.el.offset(),r={top:l.top,left:l.left};if("auto"===i){var u=e(window).height(),c=e(window).scrollTop(),d=-c+l.top-o,g=c+u-(l.top+a+o);i=Math.max(d,g)===d?"top":"bottom"}if("top"===i?r.top+=-o:r.top+=a,n!==document.body){var h,p=s.css("opacity");t.visible||s.css("opacity",0).show(),h=s.offsetParent().offset(),r.top-=h.top,r.left-=h.left,t.visible||s.css("opacity",p).hide()}"auto"===t.options.width&&(r.width=t.el.outerWidth()-2+"px"),s.css(r)}},fixPositionDetailsBox:function(){var t=this,s=e(t.detailsContainer);if(0==s.length)return!1;var n=e(window).width(),i=s.parent(),o=s.prev(),a=s.width(),l=s.offset(),r=550;i.width()>=r||(n<l.left+a&&(i.removeClass("dgwt-wcas-details-right"),i.addClass("dgwt-wcas-details-left"),s.css("left","-"+s.outerWidth()+"px")),l.left<1&&(i.removeClass("dgwt-wcas-details-left"),i.addClass("dgwt-wcas-details-right"),s.css("left",o.outerWidth()+"px")))},fixHeight:function(t,s){var n=this,i=n.options;if(1!=i.showDetailsPanel)return!1;var s,o=e("."+i.containerClass),a=e("."+i.containerDetailsClass),l=0,r=0;e("."+i.containerClass+"> *").each(function(){l+=e(this).outerHeight()}),e("."+i.containerDetailsClass+"> *").each(function(){r+=e(this).outerHeight()}),s=l>=r?l:r,(s>l||s>r)&&(o.css("height",s+"px"),a.css("height",s+"px")),"undefined"==typeof t&&(t=0),5>t?setTimeout(function(){n.fixHeight(t+1,s)},30):t=0},enableKillerFn:function(){var t=this;e(document).on("click.autocomplete",t.killerFn)},disableKillerFn:function(){var t=this;e(document).off("click.autocomplete",t.killerFn)},killSuggestions:function(){var t=this,s=e(t.suggestionsContainer).parent();t.stopKillSuggestions(),t.intervalId=window.setInterval(function(){t.visible&&(t.el.val(t.currentValue),t.hide(),s.removeClass("dgwt-wcas-open")),t.stopKillSuggestions()},50)},stopKillSuggestions:function(){window.clearInterval(this.intervalId)},isCursorAtEnd:function(){var e,t=this,s=t.el.val().length,n=t.element.selectionStart;return"number"==typeof n?n===s:document.selection?(e=document.selection.createRange(),e.moveStart("character",-s),s===e.text.length):!0},onKeyPress:function(e){var t=this;if(!t.disabled&&!t.visible&&e.which===n.DOWN&&t.currentValue)return void t.suggest();if(!t.disabled&&t.visible){switch(e.which){case n.ESC:t.el.val(t.currentValue),t.hide();break;case n.RIGHT:if(t.hint&&t.options.onHint&&t.isCursorAtEnd()){t.selectHint();break}return;case n.TAB:if(t.hint&&t.options.onHint)return void t.selectHint();if(-1===t.selectedIndex)return void t.hide();if(t.select(t.selectedIndex),t.options.tabDisabled===!1)return;break;case n.RETURN:if(-1===t.selectedIndex)return void t.hide();t.select(t.selectedIndex);break;case n.UP:t.moveUp();break;case n.DOWN:t.moveDown();break;default:return}e.stopImmediatePropagation(),e.preventDefault()}},onKeyUp:function(e){var t=this;if(!t.disabled){switch(e.which){case n.UP:case n.DOWN:return}clearInterval(t.onChangeInterval),t.currentValue!==t.el.val()&&(t.findBestHint(),t.options.deferRequestBy>0?t.onChangeInterval=setInterval(function(){t.onValueChange()},t.options.deferRequestBy):t.onValueChange())}},onValueChange:function(){var t=this,s=t.options,n=t.el.val(),i=t.getQuery(n);return t.selection&&t.currentValue!==i&&(t.selection=null,(s.onInvalidateSelection||e.noop).call(t.element)),clearInterval(t.onChangeInterval),t.currentValue=n,t.selectedIndex=-1,s.triggerSelectOnValidInput&&t.isExactMatch(i)?void t.select(0):void(i.length<s.minChars?(e("."+t.options.closeTrigger).removeClass(t.options.closeTrigger),t.hide()):t.getSuggestions(i))},isExactMatch:function(e){var t=this.suggestions;return 1===t.length&&t[0].value.toLowerCase()===e.toLowerCase()},getQuery:function(t){var s,n=this.options.delimiter;return n?(s=t.split(n),e.trim(s[s.length-1])):t},getSuggestionsLocal:function(t){var s,n=this,i=n.options,o=t.toLowerCase(),a=i.lookupFilter,l=parseInt(i.lookupLimit,10);return s={suggestions:e.grep(i.lookup,function(e){return a(e,t,o)})},l&&s.suggestions.length>l&&(s.suggestions=s.suggestions.slice(0,l)),s},getSuggestions:function(t){var s,n,i,o,a=this,l=a.options,r=l.serviceUrl;if(l.params[l.paramName]=t,n=l.ignoreParams?null:l.params,a.preloader("show",e("."+l.preloaderClass),"dgwt-wcas-inner-preloader",dgwt_wcas.preloader_url,!0),l.onSearchStart.call(a.element,l.params)!==!1){if(e.isFunction(l.lookup))return void l.lookup(t,function(e){a.suggestions=e.suggestions,a.suggest(),a.getDetails(e.suggestions[0]),l.onSearchComplete.call(a.element,t,e.suggestions)});a.isLocal?s=a.getSuggestionsLocal(t):(e.isFunction(r)&&(r=r.call(a.element,t)),i=r+"?"+e.param(n||{}),s=a.cachedResponse[i]),s&&e.isArray(s.suggestions)?(a.suggestions=s.suggestions,a.suggest(),a.getDetails(s.suggestions[0]),l.onSearchComplete.call(a.element,t,s.suggestions)):a.isBadQuery(t)?l.onSearchComplete.call(a.element,t,[]):(a.abortAjax(),o={url:r,data:n,type:l.type,dataType:l.dataType},e.extend(o,l.ajaxSettings),a.currentRequest=e.ajax(o).done(function(e){var s;a.currentRequest=null,s=l.transformResult(e,t),"undefined"!=typeof s.suggestions&&(a.processResponse(s,t,i),a.getDetails(s.suggestions[0])),l.onSearchComplete.call(a.element,t,s.suggestions)}).fail(function(e,s,n){l.onSearchError.call(a.element,t,e,s,n)}))}},getDetails:function(t){var s=this,n=s.options;if(1!=n.showDetailsPanel||e(window).width()<992||"ontouchend"in document)return!1;if(null!=t){var i,o,a=e("."+n.containerDetailsClass);s.fixHeight();var l={action:dgwt_wcas.action_result_details,post_id:null!=t.post_id?t.post_id:0,term_id:null!=t.term_id?t.term_id:0,taxonomy:null!=t.taxonomy?t.taxonomy:"",value:null!=t.value?t.value:""};i=l.action+l.post_id+l.term_id+l.taxonomy,o=s.cachedDetails[i],null!=o?(a.html(o.details),s.fixHeight(),s.fixPositionDetailsBox()):(a.html(""),s.preloader("show",a,"",dgwt_wcas.preloader_url),e.ajax({data:l,type:"post",url:dgwt_wcas.ajax_details_endpoint,success:function(e){var t="string"==typeof e?jQuery.parseJSON(e):e;s.cachedDetails[i]=t,s.preloader("hide",a,"",dgwt_wcas.preloader_url),null!=t.details?a.html(t.details):a.html("@TODO BŁĄD"),s.fixPositionDetailsBox(),s.fixHeight()},error:function(e,t){s.preloader("hide",a,"",dgwt_wcas.preloader_url),a.html(e),s.fixPositionDetailsBox(),s.fixHeight()}}))}},isBadQuery:function(e){if(!this.options.preventBadQueries)return!1;for(var t=this.badQueries,s=t.length;s--;)if(0===e.indexOf(t[s]))return!0;return!1},hide:function(){var t=this,s=e(t.suggestionsContainer);e(t.detailsContainer);e.isFunction(t.options.onHide)&&t.visible&&t.options.onHide.call(t.element,s),t.visible=!1,t.selectedIndex=-1,clearInterval(t.onChangeInterval),e(t.suggestionsContainer).hide(),e(t.detailsContainer).hide(),t.signalHint(null)},suggest:function(){if(0===this.suggestions.length)return void(this.options.showNoSuggestionNotice?this.noSuggestions():this.hide());var t,s=this,n=s.options,i=n.groupBy,o=n.formatResult,a=s.getQuery(s.currentValue),l=s.classes.suggestion,r=s.classes.selected,u=e(s.suggestionsContainer),c=e(s.detailsContainer),d=e(s.noSuggestionsContainer),g=n.beforeRender,h="",p=function(e,s){var n=e.data[i];return t===n?"":(t=n,'<div class="autocomplete-group"><strong>'+t+"</strong></div>")};return n.triggerSelectOnValidInput&&s.isExactMatch(a)?void s.select(0):(e.each(s.suggestions,function(e,t){var s="",r="",u=!1;i&&(h+=p(t,a,e)),"undefined"!=typeof t.parents&&(s=t.parents),n.showImage===!0&&"undefined"!=typeof t.thumb_html&&(u=!0),r+="undefined"!=typeof t.post_id?'data-post-id="'+t.post_id+'" ':"",r+="undefined"!=typeof t.taxonomy?'data-taxonomy="'+t.taxonomy+'" ':"",r+="undefined"!=typeof t.term_id?'data-term-id="'+t.term_id+'" ':"",h+='<div class="'+l+'" data-index="'+e+'" '+r+">",u&&(h+='<span class="dgwt-wcas-si">'+t.thumb_html+"</span>"),h+=u?'<div class="dgwt-wcas-content-wrapp">':"",h+='<span class="dgwt-wcas-st">'+o(t,a)+s+"</span>",n.showPrice===!0&&"undefined"!=typeof t.price&&(h+='<span class="dgwt-wcas-sp">'+t.price+"</span>"),n.showDescription===!0&&"undefined"!=typeof t.desc&&(h+='<span class="dgwt-wcas-sd">'+t.desc+"</span>"),n.showFeaturedBadge===!0&&t.on_sale===!0&&(h+='<span class="dgwt-wcas-badge dgwt-wcas-badge-os">'+n.saleBadgeText+"</span>"),n.showFeaturedBadge===!0&&t.featured===!0&&(h+='<span class="dgwt-wcas-badge dgwt-wcas-badge-f">'+n.featuredBadgeText+"</span>"),h+=u?"</div>":"",h+="</div>"}),this.adjustContainerWidth(),d.detach(),u.html(h),e.isFunction(g)&&g.call(s.element,u),s.fixPosition(),u.show(),u.parent().addClass("dgwt-wcas-open"),n.showDetailsPanel===!0&&c.show(),n.autoSelectFirst&&(s.selectedIndex=0,u.scrollTop(0),u.children("."+l).first().addClass(r)),s.visible=!0,void s.findBestHint())},noSuggestions:function(){var t=this,s=e(t.suggestionsContainer),n=e(t.noSuggestionsContainer);this.adjustContainerWidth(),n.detach(),s.empty(),s.append(n),t.fixPosition(),s.show(),t.visible=!0},adjustContainerWidth:function(){var t,s=this,n=s.options,i=e(s.suggestionsContainer).parent(),o=e(s.suggestionsContainer),a=e(s.detailsContainer),l=550;return"auto"===n.width&&(t=s.el.outerWidth(),o.css("width",t+"px")),i.width()>=l&&n.showDetailsPanel===!0?(i.addClass("dgwt-wcas-full-width"),o.outerWidth(300),a.innerWidth(i.width()-300),i.removeClass("dgwt-wcas-details-left"),i.removeClass("dgwt-wcas-details-right"),void(n.is_rtl===!0?(a.css("left","0"),o.css("right","0")):(a.css("right","0"),o.css("left","0")))):void("left"===n.cointainerDetailsPos?(a.parent().addClass("dgwt-wcas-details-left"),a.css("left","-"+a.outerWidth()+"px")):(a.parent().addClass("dgwt-wcas-details-right"),a.css("left",i.outerWidth()+"px")))},findBestHint:function(){var t=this,s=t.el.val().toLowerCase(),n=null;s&&(e.each(t.suggestions,function(e,t){var i=0===t.value.toLowerCase().indexOf(s);return i&&(n=t),!i}),t.signalHint(n))},signalHint:function(t){var s="",n=this;t&&(s=n.currentValue+t.value.substr(n.currentValue.length)),n.hintValue!==s&&(n.hintValue=s,n.hint=t,(this.options.onHint||e.noop)(s))},preloader:function(t,s,n,i,o){var a,l="dgwt-wcas-preloader-wrapp",r=null==n?l:l+" "+n;if(1==dgwt_wcas.show_preloader&&0!=s.length)return""==i&&o===!0?void("hide"===t?s.removeClass(n):s.addClass(n)):"hide"===t?void e(l).remove():void("show"===t&&(a=""!=i?'<div class="'+r+'"><img src="'+i+'" /></div>':'<div class="'+r+'"><div class="dgwt-wcas-default-preloader"></div></div>',s.html(a)))},verifySuggestionsFormat:function(t){return t.length&&"string"==typeof t[0]?e.map(t,function(e){return{value:e,data:null}}):t},validateOrientation:function(t,s){return t=e.trim(t||"").toLowerCase(),-1===e.inArray(t,["auto","bottom","top"])&&(t=s),t},processResponse:function(e,t,s){var n=this,i=n.options;e.suggestions=n.verifySuggestionsFormat(e.suggestions),i.noCache||(n.cachedResponse[s]=e,i.preventBadQueries&&0===e.suggestions.length&&n.badQueries.push(t)),t===n.getQuery(n.currentValue)&&(n.suggestions=e.suggestions,n.suggest())},activate:function(t){var s,n=this,i=n.classes.selected,o=e(n.suggestionsContainer),a=o.find("."+n.classes.suggestion);return o.find("."+i).removeClass(i),n.selectedIndex=t,-1!==n.selectedIndex&&a.length>n.selectedIndex?(s=a.get(n.selectedIndex),e(s).addClass(i),s):null},selectHint:function(){var t=this,s=e.inArray(t.hint,t.suggestions);t.select(s)},select:function(e){var t=this;t.hide(),t.onSelect(e)},moveUp:function(){var t=this;if(-1!==t.selectedIndex)return 0===t.selectedIndex?(e(t.suggestionsContainer).children().first().removeClass(t.classes.selected),t.selectedIndex=-1,t.el.val(t.currentValue),void t.findBestHint()):void t.adjustScroll(t.selectedIndex-1)},moveDown:function(){var e=this;e.selectedIndex!==e.suggestions.length-1&&e.adjustScroll(e.selectedIndex+1)},adjustScroll:function(t){var s=this,n=s.activate(t);if(n){var i,o,a,l=e(n).outerHeight();i=n.offsetTop,o=e(s.suggestionsContainer).scrollTop(),a=o+s.options.maxHeight-l,o>i?e(s.suggestionsContainer).scrollTop(i):i>a&&e(s.suggestionsContainer).scrollTop(i-s.options.maxHeight+l),s.options.preserveInput||s.el.val(s.getValue(s.suggestions[t].value)),s.signalHint(null)}},onSelect:function(t){var s=this,n=s.options.onSelect,i=s.suggestions[t];s.currentValue=s.getValue(i.value),s.currentValue===s.el.val()||s.options.preserveInput||s.el.val(s.currentValue),-1!=i.id&&(window.location.href=i.url),s.signalHint(null),s.suggestions=[],s.selection=i,e.isFunction(n)&&n.call(s.element,i)},onMouseOver:function(t){var s=this,n=s.options.onMouseOver,i=s.suggestions[t];s.getDetails(i),e.isFunction(n)&&n.call(s.element,i)},onMouseLeave:function(t){var s=this,n=s.options.onMouseLeave,i=s.suggestions[t];e.isFunction(n)&&n.call(s.element,i)},getValue:function(e){var t,s,n=this,i=n.options.delimiter;return i?(t=n.currentValue,s=t.split(i),1===s.length?e:t.substr(0,t.length-s[s.length-1].length)+e):e},dispose:function(){var t=this;t.el.off(".autocomplete").removeData("autocomplete"),t.disableKillerFn(),e(window).off("resize.autocomplete",t.fixPositionCapture),e(t.suggestionsContainer).remove()}},e.fn.dgwtWcasAutocomplete=function(s,n){var i="autocomplete";return 0===arguments.length?this.first().data(i):this.each(function(){var o=e(this),a=o.data(i);"string"==typeof s?a&&"function"==typeof a[s]&&a[s](n):(a&&a.dispose&&a.dispose(),a=new t(this,s),o.data(i,a))})},function(){e(document).ready(function(){e(".dgwt-wcas-search-submit").length>0&&e(".dgwt-wcas-preloader").css("right",e(".dgwt-wcas-search-submit").outerWidth()+"px");var t=1==dgwt_wcas.show_details_box?!0:!1;(jQuery(window).width()<992||"ontouchend"in document)&&(t=!1),e(".dgwt-wcas-search-input").dgwtWcasAutocomplete({minChars:dgwt_wcas.min_chars,autoSelectFirst:!0,triggerSelectOnValidInput:!1,serviceUrl:dgwt_wcas.ajax_search_endpoint,paramName:"dgwt_wcas_keyword",showDetailsPanel:t,showImage:1==dgwt_wcas.show_images?!0:!1,showPrice:1==dgwt_wcas.show_price?!0:!1,showDescription:1==dgwt_wcas.show_desc?!0:!1,showSaleBadge:1==dgwt_wcas.show_sale_badge?!0:!1,showFeaturedBadge:1==dgwt_wcas.show_featured_badge?!0:!1,saleBadgeText:dgwt_wcas.t.sale_badge,featuredBadgeText:dgwt_wcas.t.featured_badge,cointainerDetailsPos:dgwt_wcas.details_box_pos,is_rtl:1==dgwt_wcas.is_rtl?!0:!1})})}()});
includes/admin/admin-menus.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Submenu page
5
+ */
6
+ // Exit if accessed directly
7
+ if ( !defined( 'ABSPATH' ) ) {
8
+ exit;
9
+ }
10
+
11
+ class DGWT_WCAS_Admin_Menu {
12
+
13
+ public function __construct() {
14
+
15
+ add_action( 'admin_menu', array( $this, 'add_menu' ), 20 );
16
+ }
17
+
18
+ /**
19
+ * Add meun items
20
+ */
21
+ public function add_menu() {
22
+
23
+ add_menu_page( __( 'Ajax Search for WooCommerce', DGWT_WCAS_DOMAIN ), __( 'Woo Ajax Search', DGWT_WCAS_DOMAIN ), 'manage_options', 'dgwt_wcas_settings', array( $this, 'settings_page' ), DGWT_WCAS_URL . '/assets/img/admin-icon.svg', 56);
24
+ }
25
+
26
+ /**
27
+ * Settings page
28
+ */
29
+ public function settings_page() {
30
+ DGWT_WCAS_Settings::output();
31
+ }
32
+
33
+ }
34
+
35
+ $admin_menu = new DGWT_WCAS_Admin_Menu();
36
+
includes/admin/settings/class-settings-api.php ADDED
@@ -0,0 +1,687 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Adapted from https://github.com/tareq1988/wordpress-settings-api-class
4
+ *
5
+ */
6
+ /**
7
+ * weDevs Settings API wrapper class
8
+ *
9
+ * @version 1.1
10
+ *
11
+ * @author Tareq Hasan <tareq@weDevs.com>
12
+ * @link http://tareq.weDevs.com Tareq's Planet
13
+ * @example src/settings-api.php How to use the class
14
+ */
15
+ // Exit if accessed directly
16
+ if ( !defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ class DGWT_WCAS_Settings_API {
21
+
22
+ /**
23
+ * settings sections array
24
+ *
25
+ * @var array
26
+ */
27
+ private $settings_sections = array();
28
+
29
+ /**
30
+ * Settings fields array
31
+ *
32
+ * @var array
33
+ */
34
+ private $settings_fields = array();
35
+
36
+ /**
37
+ * Singleton instance
38
+ *
39
+ * @var object
40
+ */
41
+ private static $_instance;
42
+
43
+ /*
44
+ * Name
45
+ */
46
+ private $name;
47
+
48
+ /*
49
+ * Prefix
50
+ */
51
+ private $prefix;
52
+
53
+ /*
54
+ * Constructor
55
+ *
56
+ * @param string $prefix - unique prefix for CSS classes and other names
57
+ */
58
+
59
+ public function __construct( $name = '' ) {
60
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
61
+
62
+ $this->name = sanitize_title( $name );
63
+ $this->prefix = sanitize_title( $name ) . '-';
64
+ }
65
+
66
+ /**
67
+ * Enqueue scripts and styles
68
+ */
69
+ function admin_enqueue_scripts() {
70
+ wp_enqueue_style( 'wp-color-picker' );
71
+
72
+ wp_enqueue_media();
73
+ wp_enqueue_script( 'wp-color-picker' );
74
+ wp_enqueue_script( 'jquery' );
75
+ }
76
+
77
+ /**
78
+ * Set settings sections
79
+ *
80
+ * @param array $sections setting sections array
81
+ */
82
+ function set_sections( $sections ) {
83
+ $this->settings_sections = $sections;
84
+
85
+ return $this;
86
+ }
87
+
88
+ /**
89
+ * Add a single section
90
+ *
91
+ * @param array $section
92
+ */
93
+ function add_section( $section ) {
94
+ $this->settings_sections[] = $section;
95
+
96
+ return $this;
97
+ }
98
+
99
+ /**
100
+ * Set settings fields
101
+ *
102
+ * @param array $fields settings fields array
103
+ */
104
+ function set_fields( $fields ) {
105
+ $this->settings_fields = $fields;
106
+
107
+ return $this;
108
+ }
109
+
110
+ function add_field( $section, $field ) {
111
+ $defaults = array(
112
+ 'name' => '',
113
+ 'label' => '',
114
+ 'desc' => '',
115
+ 'type' => 'text'
116
+ );
117
+
118
+ $arg = wp_parse_args( $field, $defaults );
119
+ $this->settings_fields[ $section ][] = $arg;
120
+
121
+ return $this;
122
+ }
123
+
124
+ /**
125
+ * Initialize and registers the settings sections and fileds to WordPress
126
+ *
127
+ * Usually this should be called at `admin_init` hook.
128
+ *
129
+ * This function gets the initiated settings sections and fields. Then
130
+ * registers them to WordPress and ready for use.
131
+ */
132
+ public function settings_init() {
133
+
134
+ if ( false == get_option( $this->name ) ) {
135
+ add_option( $this->name );
136
+ }
137
+
138
+ //Register settings sections
139
+ foreach ( $this->settings_sections as $section ) {
140
+
141
+
142
+ if ( isset( $section[ 'desc' ] ) && !empty( $section[ 'desc' ] ) ) {
143
+ $section[ 'desc' ] = '<div class="inside">' . $section[ 'desc' ] . '</div>';
144
+ $callback = create_function( '', 'echo "' . str_replace( '"', '\"', $section[ 'desc' ] ) . '";' );
145
+ } else if ( isset( $section[ 'callback' ] ) ) {
146
+ $callback = $section[ 'callback' ];
147
+ } else {
148
+ $callback = null;
149
+ }
150
+ add_settings_section( $section[ 'id' ], $section[ 'title' ], $callback, $section[ 'id' ] );
151
+ }
152
+
153
+
154
+
155
+ //Register settings fields
156
+ foreach ( $this->settings_fields as $section => $field ) {
157
+ foreach ( $field as $option ) {
158
+ $type = isset( $option[ 'type' ] ) ? $option[ 'type' ] : 'text';
159
+
160
+ $args = array(
161
+ 'id' => $option[ 'name' ],
162
+ 'label_for' => $args[ 'label_for' ] = "$this->name[{$option[ 'name' ]}]",
163
+ 'desc' => isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : '',
164
+ 'name' => $option[ 'label' ],
165
+ 'size' => isset( $option[ 'size' ] ) ? $option[ 'size' ] : null,
166
+ 'options' => isset( $option[ 'options' ] ) ? $option[ 'options' ] : '',
167
+ 'std' => isset( $option[ 'default' ] ) ? $option[ 'default' ] : '',
168
+ 'sanitize_callback' => isset( $option[ 'sanitize_callback' ] ) ? $option[ 'sanitize_callback' ] : '',
169
+ 'type' => $type,
170
+ );
171
+
172
+ add_settings_field( "$this->name[" . $option[ 'name' ] . ']', $option[ 'label' ], array( $this, 'callback_' . $type ), $section, $section, $args );
173
+ }
174
+ }
175
+
176
+ // Creates our settings in the options table
177
+ foreach ( $this->settings_sections as $section ) {
178
+ register_setting( $section[ 'id' ], $this->name, array( $this, 'sanitize_options' ) );
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Get field description for display
184
+ *
185
+ * @param array $args settings field args
186
+ */
187
+ public function get_field_description( $args ) {
188
+ if ( !empty( $args[ 'desc' ] ) ) {
189
+
190
+ $css_class = $this->prefix . 'description-field';
191
+
192
+ $desc = sprintf( '<p class="%s">%s</p>', $css_class, $args[ 'desc' ] );
193
+ } else {
194
+ $desc = '';
195
+ }
196
+
197
+ return $desc;
198
+ }
199
+
200
+ /**
201
+ * Head
202
+ */
203
+ function callback_head( $args ) {
204
+
205
+ echo '<span class="dgwt-wcas-settings-hr"></span>';
206
+ }
207
+
208
+ /**
209
+ * Displays a text field for a settings field
210
+ *
211
+ * @param array $args settings field args
212
+ */
213
+ function callback_text( $args ) {
214
+
215
+ $value = esc_attr( $this->get_option( $args[ 'id' ], $args[ 'std' ] ) );
216
+ $size = isset( $args[ 'size' ] ) && !is_null( $args[ 'size' ] ) ? $args[ 'size' ] : 'regular';
217
+ $type = isset( $args[ 'type' ] ) ? $args[ 'type' ] : 'text';
218
+
219
+ $html = sprintf( '<input type="%1$s" class="%2$s-text" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s"/>', $type, $size, $this->name, $args[ 'id' ], $value );
220
+ $html .= $this->get_field_description( $args );
221
+
222
+ echo $html;
223
+ }
224
+
225
+ /**
226
+ * Displays a url field for a settings field
227
+ *
228
+ * @param array $args settings field args
229
+ */
230
+ function callback_url( $args ) {
231
+ $this->callback_text( $args );
232
+ }
233
+
234
+ /**
235
+ * Displays a number field for a settings field
236
+ *
237
+ * @param array $args settings field args
238
+ */
239
+ function callback_number( $args ) {
240
+ $this->callback_text( $args );
241
+ }
242
+
243
+ /**
244
+ * Displays a checkbox for a settings field
245
+ *
246
+ * @param array $args settings field args
247
+ */
248
+ function callback_checkbox( $args ) {
249
+
250
+ $value = esc_attr( $this->get_option( $args[ 'id' ], $args[ 'std' ] ) );
251
+
252
+ $html = '<fieldset>';
253
+ $html .= sprintf( '<label for="%1$s[%2$s]">', $this->name, $args[ 'id' ] );
254
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" />', $this->name, $args[ 'id' ] );
255
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[%2$s]" value="on" %3$s />', $this->name, $args[ 'id' ], checked( $value, 'on', false ) );
256
+ $html .= sprintf( '<p class="%1$s-description-field">%2$s</p></label>', $this->name, $args[ 'desc' ] );
257
+ $html .= '</fieldset>';
258
+
259
+ echo $html;
260
+ }
261
+
262
+ /**
263
+ * Displays a multicheckbox a settings field
264
+ *
265
+ * @param array $args settings field args
266
+ */
267
+ function callback_multicheck( $args ) {
268
+
269
+ $value = $this->get_option( $args[ 'id' ], $args[ 'std' ] );
270
+
271
+
272
+ $html = '<fieldset>';
273
+ foreach ( $args[ 'options' ] as $key => $label ) {
274
+ $checked = isset( $value[ $key ] ) ? $value[ $key ] : '0';
275
+ $html .= sprintf( '<label for="%1$s[%2$s][%3$s]">', $this->name, $args[ 'id' ], $key );
276
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s" %4$s />', $this->name, $args[ 'id' ], $key, checked( $checked, $key, false ) );
277
+ $html .= sprintf( '%1$s</label><br>', $label );
278
+ }
279
+ $html .= $this->get_field_description( $args );
280
+ $html .= '</fieldset>';
281
+
282
+ echo $html;
283
+ }
284
+
285
+ /**
286
+ * Displays a multicheckbox a settings field
287
+ *
288
+ * @param array $args settings field args
289
+ */
290
+ function callback_radio( $args ) {
291
+
292
+ $value = $this->get_option( $args[ 'id' ], $args[ 'std' ] );
293
+
294
+ $html = '<fieldset>';
295
+ foreach ( $args[ 'options' ] as $key => $label ) {
296
+ $html .= sprintf( '<label for="%1$s%2$s[%3$s][%4$s]">', $this->prefix, $this->name, $args[ 'id' ], $key );
297
+ $html .= sprintf( '<input type="radio" class="radio" id="%1$s%2$s[%3$s][%4$s]" name="%2$s[%3$s]" value="%4$s" %5$s />', $this->prefix, $this->name, $args[ 'id' ], $key, checked( $value, $key, false ) );
298
+ $html .= sprintf( '%1$s</label><br>', $label );
299
+ }
300
+ $html .= $this->get_field_description( $args );
301
+ $html .= '</fieldset>';
302
+
303
+ echo $html;
304
+ }
305
+
306
+ /**
307
+ * Displays a selectbox for a settings field
308
+ *
309
+ * @param array $args settings field args
310
+ */
311
+ function callback_select( $args ) {
312
+
313
+ $value = esc_attr( $this->get_option( $args[ 'id' ], $args[ 'std' ] ) );
314
+ $size = isset( $args[ 'size' ] ) && !is_null( $args[ 'size' ] ) ? $args[ 'size' ] : 'regular';
315
+
316
+ $html = sprintf( '<select class="%1$s" name="%2$s[%3$s]" id="%2$s[%3$s]">', $size, $this->name, $args[ 'id' ] );
317
+ foreach ( $args[ 'options' ] as $key => $label ) {
318
+ $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $value, $key, false ), $label );
319
+ }
320
+ $html .= sprintf( '</select>' );
321
+ $html .= $this->get_field_description( $args );
322
+
323
+ echo $html;
324
+ }
325
+
326
+ /**
327
+ * Displays a textarea for a settings field
328
+ *
329
+ * @param array $args settings field args
330
+ */
331
+ function callback_textarea( $args ) {
332
+
333
+ $value = esc_textarea( $this->get_option( $args[ 'id' ], $args[ 'std' ] ) );
334
+ $size = isset( $args[ 'size' ] ) && !is_null( $args[ 'size' ] ) ? $args[ 'size' ] : 'regular';
335
+
336
+ $html = sprintf( '<textarea rows="5" cols="55" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]">%4$s</textarea>', $size, $this->name, $args[ 'id' ], $value );
337
+ $html .= $this->get_field_description( $args );
338
+
339
+ echo $html;
340
+ }
341
+
342
+ /**
343
+ * Displays a textarea for a settings field
344
+ *
345
+ * @param array $args settings field args
346
+ * @return string
347
+ */
348
+ function callback_html( $args ) {
349
+ echo $this->get_field_description( $args );
350
+ }
351
+
352
+ /**
353
+ * Displays a rich text textarea for a settings field
354
+ *
355
+ * @param array $args settings field args
356
+ */
357
+ function callback_wysiwyg( $args ) {
358
+
359
+ $value = $this->get_option( $args[ 'id' ], $args[ 'std' ] );
360
+ $size = isset( $args[ 'size' ] ) && !is_null( $args[ 'size' ] ) ? $args[ 'size' ] : '500px';
361
+
362
+ echo '<div style="max-width: ' . $size . ';">';
363
+
364
+ $editor_settings = array(
365
+ 'teeny' => true,
366
+ 'textarea_name' => $this->name . '[' . $args[ 'id' ] . ']',
367
+ 'textarea_rows' => 10
368
+ );
369
+ if ( isset( $args[ 'options' ] ) && is_array( $args[ 'options' ] ) ) {
370
+ $editor_settings = array_merge( $editor_settings, $args[ 'options' ] );
371
+ }
372
+
373
+ wp_editor( $value, $this->name . '-' . $args[ 'id' ], $editor_settings );
374
+
375
+ echo '</div>';
376
+
377
+ echo $this->get_field_description( $args );
378
+ }
379
+
380
+ /**
381
+ * Displays a file upload field for a settings field
382
+ *
383
+ * @param array $args settings field args
384
+ */
385
+ function callback_file( $args ) {
386
+
387
+ $value = esc_attr( $this->get_option( $args[ 'id' ], $args[ 'std' ] ) );
388
+ $size = isset( $args[ 'size' ] ) && !is_null( $args[ 'size' ] ) ? $args[ 'size' ] : 'regular';
389
+ $id = $this->name . '[' . $args[ 'id' ] . ']';
390
+ $label = isset( $args[ 'options' ][ 'button_label' ] ) ?
391
+ $args[ 'options' ][ 'button_label' ] :
392
+ __( 'Choose File' );
393
+
394
+ $html = sprintf( '<input type="text" class="%1$s-text %2$surl" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s"/>', $size, $this->prefix, $this->name, $args[ 'id' ], $value );
395
+ $html .= '<input type="button" class="button ' . $this->prefix . 'browse" value="' . $label . '" />';
396
+ $html .= $this->get_field_description( $args );
397
+
398
+ echo $html;
399
+ }
400
+
401
+ /**
402
+ * Displays a password field for a settings field
403
+ *
404
+ * @param array $args settings field args
405
+ */
406
+ function callback_password( $args ) {
407
+
408
+ $value = esc_attr( $this->get_option( $args[ 'id' ], $args[ 'std' ] ) );
409
+ $size = isset( $args[ 'size' ] ) && !is_null( $args[ 'size' ] ) ? $args[ 'size' ] : 'regular';
410
+
411
+ $html = sprintf( '<input type="password" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $this->name, $args[ 'id' ], $value );
412
+ $html .= $this->get_field_description( $args );
413
+
414
+ echo $html;
415
+ }
416
+
417
+ /**
418
+ * Displays a color picker field for a settings field
419
+ *
420
+ * @param array $args settings field args
421
+ */
422
+ function callback_color( $args ) {
423
+
424
+ $value = esc_attr( $this->get_option( $args[ 'id' ], $args[ 'std' ] ) );
425
+ $size = isset( $args[ 'size' ] ) && !is_null( $args[ 'size' ] ) ? $args[ 'size' ] : 'regular';
426
+
427
+ $html = sprintf( '<input type="text" class="%1$s-text wp-color-picker-field" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s" data-default-color="%5$s" />', $size, $this->name, $args[ 'id' ], $value, $args[ 'std' ] );
428
+ $html .= $this->get_field_description( $args );
429
+
430
+ echo $html;
431
+ }
432
+
433
+ /**
434
+ * Displays a color picker field for a settings field
435
+ *
436
+ * @param array $args settings field args
437
+ */
438
+ function callback_desc( $args ) {
439
+
440
+ $html = '';
441
+ if ( isset( $args[ 'desc' ] ) && !empty( $args[ 'desc' ] ) ) {
442
+ $html .= '<div class="dgwt-wcas-settings-info">';
443
+ $html .= wp_kses_post( $args[ 'desc' ] );
444
+ $html .= '</div>';
445
+ }
446
+
447
+ echo $html;
448
+ }
449
+
450
+ /**
451
+ * Displays a color picker field for a settings field
452
+ *
453
+ * @param array $args settings field args
454
+ */
455
+ function callback_datepicker( $args ) {
456
+
457
+ $value = esc_attr( $this->get_option( $args[ 'id' ], $args[ 'std' ] ) );
458
+ $size = isset( $args[ 'size' ] ) && !is_null( $args[ 'size' ] ) ? $args[ 'size' ] : 'regular';
459
+
460
+ $html = sprintf( '<input type="text" class="%1$s-text dgwt-datepicker-field" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s" />', $size, $this->name, $args[ 'id' ], $value );
461
+ $html .= $this->get_field_description( $args );
462
+
463
+ echo $html;
464
+ }
465
+
466
+ /**
467
+ * Sanitize callback for Settings API
468
+ */
469
+ function sanitize_options( $options ) {
470
+
471
+ if ( !isset( $options ) || empty( $options ) || !is_array( $options ) ) {
472
+ return $options;
473
+ }
474
+
475
+ foreach ( $options as $option_slug => $option_value ) {
476
+ $sanitize_callback = $this->get_sanitize_callback( $option_slug );
477
+
478
+ // If callback is set, call it
479
+ if ( $sanitize_callback ) {
480
+ $options[ $option_slug ] = call_user_func( $sanitize_callback, $option_value );
481
+ continue;
482
+ }
483
+ }
484
+
485
+ return $options;
486
+ }
487
+
488
+ /**
489
+ * Get sanitization callback for given option slug
490
+ *
491
+ * @param string $slug option slug
492
+ *
493
+ * @return mixed string or bool false
494
+ */
495
+ function get_sanitize_callback( $slug = '' ) {
496
+ if ( empty( $slug ) ) {
497
+ return false;
498
+ }
499
+
500
+ // Iterate over registered fields and see if we can find proper callback
501
+ foreach ( $this->settings_fields as $section => $options ) {
502
+ foreach ( $options as $option ) {
503
+ if ( $option[ 'name' ] != $slug ) {
504
+ continue;
505
+ }
506
+
507
+ // Return the callback name
508
+ return isset( $option[ 'sanitize_callback' ] ) && is_callable( $option[ 'sanitize_callback' ] ) ? $option[ 'sanitize_callback' ] : false;
509
+ }
510
+ }
511
+
512
+ return false;
513
+ }
514
+
515
+ /**
516
+ * Get the value of a settings field
517
+ *
518
+ * @param string $option settings field name
519
+ * @param string $default default text if it's not found
520
+ * @return string
521
+ */
522
+ function get_option( $option, $default = '' ) {
523
+
524
+ $options = get_option( $this->name );
525
+
526
+ if ( isset( $options[ $option ] ) ) {
527
+ return $options[ $option ];
528
+ }
529
+
530
+ return $default;
531
+ }
532
+
533
+ /**
534
+ * Show navigations as tab
535
+ *
536
+ * Shows all the settings section labels as tab
537
+ */
538
+ function show_navigation() {
539
+ $html = '<h2 class="nav-tab-wrapper ' . $this->prefix . 'nav-tab-wrapper">';
540
+
541
+ foreach ( $this->settings_sections as $tab ) {
542
+ $html .= sprintf( '<a href="#%1$s" class="nav-tab" id="%1$s-tab">%2$s</a>', $tab[ 'id' ], $tab[ 'title' ] );
543
+ }
544
+
545
+ $html .= '</h2>';
546
+
547
+ echo $html;
548
+ }
549
+
550
+ /**
551
+ * Show the section settings forms
552
+ *
553
+ * This function displays every sections in a different form
554
+ */
555
+ function show_forms() {
556
+ ?>
557
+ <div class="metabox-holder">
558
+ <form class="dgwt-eq-settings-form" method="post" action="options.php">
559
+ <?php foreach ( $this->settings_sections as $form ) { ?>
560
+ <div id="<?php echo $form[ 'id' ]; ?>" class="<?php echo $this->prefix; ?>group" style="display: none;">
561
+
562
+ <?php
563
+ do_action( $this->prefix . 'form_top_' . $form[ 'id' ], $form );
564
+ settings_fields( $form[ 'id' ] );
565
+ do_settings_sections( $form[ 'id' ] );
566
+ do_action( $this->prefix . 'form_bottom_' . $form[ 'id' ], $form );
567
+ ?>
568
+ <div style="padding-left: 10px">
569
+ <?php submit_button(); ?>
570
+ </div>
571
+
572
+ </div>
573
+ <?php } ?>
574
+ </form>
575
+ </div>
576
+ <?php
577
+ $this->script();
578
+ }
579
+
580
+ /**
581
+ * Tabbable JavaScript codes & Initiate Color Picker
582
+ *
583
+ * This code uses localstorage for displaying active tabs
584
+ */
585
+ function script() {
586
+ ?>
587
+ <script>
588
+ jQuery( document ).ready( function ( $ ) {
589
+ //Initiate Color Picker
590
+ if ( $( '.wp-color-picker-field' ).length > 0 ) {
591
+ $( '.wp-color-picker-field' ).wpColorPicker();
592
+ }
593
+
594
+ // Switches option sections
595
+ $( '.<?php echo $this->prefix; ?>group' ).hide();
596
+ var activetab = '';
597
+ var maybe_active = '';
598
+
599
+ if ( typeof ( localStorage ) != 'undefined' ) {
600
+ maybe_active = localStorage.getItem( '<?php echo $this->prefix; ?>settings-active-tab' );
601
+
602
+ if ( maybe_active ) {
603
+
604
+ // Check if tabs exists
605
+ $( '.<?php echo $this->prefix; ?>nav-tab-wrapper a' ).each( function () {
606
+
607
+ if ( $( this ).attr( 'href' ) === maybe_active ) {
608
+ activetab = maybe_active;
609
+ }
610
+ } );
611
+
612
+ }
613
+ }
614
+
615
+ if ( activetab != '' && $( activetab ).length ) {
616
+ $( activetab ).fadeIn();
617
+ } else {
618
+ $( '.<?php echo $this->prefix; ?>group:first' ).fadeIn();
619
+ }
620
+ $( '.<?php echo $this->prefix; ?>group .collapsed' ).each( function () {
621
+ $( this ).find( 'input:checked' ).parent().parent().parent().nextAll().each(
622
+ function () {
623
+ if ( $( this ).hasClass( 'last' ) ) {
624
+ $( this ).removeClass( 'hidden' );
625
+ return false;
626
+ }
627
+ $( this ).filter( '.hidden' ).removeClass( 'hidden' );
628
+ } );
629
+ } );
630
+
631
+ if ( activetab != '' && $( activetab + '-tab' ).length ) {
632
+ $( activetab + '-tab' ).addClass( 'nav-tab-active' );
633
+ } else {
634
+ $( '.<?php echo $this->prefix; ?>nav-tab-wrapper a:first' ).addClass( 'nav-tab-active' );
635
+ }
636
+ $( '.<?php echo $this->prefix; ?>nav-tab-wrapper a' ).click( function ( evt ) {
637
+
638
+ if ( typeof ( localStorage ) != 'undefined' ) {
639
+ localStorage.setItem( '<?php echo $this->prefix; ?>settings-active-tab', $( this ).attr( 'href' ) );
640
+ }
641
+
642
+ $( '.<?php echo $this->prefix; ?>nav-tab-wrapper a' ).removeClass( 'nav-tab-active' );
643
+
644
+ $( this ).addClass( 'nav-tab-active' ).blur();
645
+ var clicked_group = $( this ).attr( 'href' );
646
+
647
+
648
+ $( '.<?php echo $this->prefix; ?>group' ).hide();
649
+ $( clicked_group ).fadeIn();
650
+ evt.preventDefault();
651
+ } );
652
+
653
+ $( '.<?php echo $this->prefix; ?>browse' ).on( 'click', function ( event ) {
654
+ event.preventDefault();
655
+
656
+ var self = $( this );
657
+
658
+ // Create the media frame.
659
+ var file_frame = wp.media.frames.file_frame = wp.media( {
660
+ title: self.data( 'uploader_title' ),
661
+ button: {
662
+ text: self.data( 'uploader_button_text' ),
663
+ },
664
+ multiple: false
665
+ } );
666
+
667
+ file_frame.on( 'select', function () {
668
+ attachment = file_frame.state().get( 'selection' ).first().toJSON();
669
+
670
+ self.prev( '.<?php echo $this->prefix; ?>url' ).val( attachment.url );
671
+ } );
672
+
673
+ // Finally, open the modal
674
+ file_frame.open();
675
+ } );
676
+ } );
677
+ </script>
678
+
679
+ <style type="text/css">
680
+ /** WordPress 3.8 Fix **/
681
+ .form-table th { padding: 20px 10px; }
682
+ #wpbody-content .metabox-holder { padding-top: 5px; }
683
+ </style>
684
+ <?php
685
+ }
686
+
687
+ }
includes/admin/settings/class-settings.php ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Settings API data
5
+ */
6
+ class DGWT_WCAS_Settings {
7
+ /*
8
+ * @var string
9
+ * Unique settings slug
10
+ */
11
+
12
+ private $setting_slug = DGWT_WCAS_SETTINGS_KEY;
13
+
14
+ /*
15
+ * @var array
16
+ * All options values in one array
17
+ */
18
+ public $opt;
19
+
20
+ /*
21
+ * @var object
22
+ * Settings API object
23
+ */
24
+ public $settings_api;
25
+
26
+ public function __construct() {
27
+ global $dgwt_wcas_settings;
28
+
29
+ // Set global variable with settings
30
+ $settings = get_option( $this->setting_slug );
31
+ if ( !isset( $settings ) || empty( $settings ) ) {
32
+ $dgwt_wcas_settings = array();
33
+ } else {
34
+ $dgwt_wcas_settings = $settings;
35
+ }
36
+
37
+ $this->opt = $dgwt_wcas_settings;
38
+
39
+ $this->settings_api = new DGWT_WCAS_Settings_API( $this->setting_slug );
40
+
41
+ add_action( 'admin_init', array( $this, 'settings_init' ) );
42
+ }
43
+
44
+ /*
45
+ * Set sections and fields
46
+ */
47
+
48
+ public function settings_init() {
49
+
50
+ //Set the settings
51
+ $this->settings_api->set_sections( $this->settings_sections() );
52
+ $this->settings_api->set_fields( $this->settings_fields() );
53
+
54
+ //Initialize settings
55
+ $this->settings_api->settings_init();
56
+ }
57
+
58
+ /*
59
+ * Set settings sections
60
+ *
61
+ * @return array settings sections
62
+ */
63
+
64
+ public function settings_sections() {
65
+
66
+ $sections = array(
67
+ array(
68
+ 'id' => 'dgwt_wcas_basic',
69
+ 'title' => __( 'Basic', DGWT_WCAS_DOMAIN )
70
+ ),
71
+ array(
72
+ 'id' => 'dgwt_wcas_advanced',
73
+ 'title' => __( 'Advanced', DGWT_WCAS_DOMAIN )
74
+ ),
75
+ array(
76
+ 'id' => 'dgwt_wcas_details_box',
77
+ 'title' => __( 'Extra Details', DGWT_WCAS_DOMAIN )
78
+ ),
79
+ array(
80
+ 'id' => 'dgwt_wcas_style',
81
+ 'title' => __( 'Style', DGWT_WCAS_DOMAIN )
82
+ ),
83
+ // array(
84
+ // 'id' => 'dgwt_wcas_performance',
85
+ // 'title' => __( 'Performance', DGWT_WCAS_DOMAIN )
86
+ // )
87
+ );
88
+ return apply_filters( 'dgwt_wcas_settings_sections', $sections );
89
+ }
90
+
91
+ /**
92
+ * Create settings fields
93
+ *
94
+ * @return array settings fields
95
+ */
96
+ function settings_fields() {
97
+ $settings_fields = array(
98
+ 'dgwt_wcas_basic' => apply_filters( 'dgwt_wcas_basic_settings', array(
99
+ array(
100
+ 'name' => 'how_to_use',
101
+ 'label' => __( 'How to use?', DGWT_WCAS_DOMAIN ),
102
+ 'type' => 'desc',
103
+ 'desc' => dgwt_wcas_how_to_use_html(),
104
+ ),
105
+ array(
106
+ 'name' => 'suggestions_limit',
107
+ 'label' => __( 'Suggestions limit', DGWT_WCAS_DOMAIN ),
108
+ 'type' => 'number',
109
+ 'size' => 'small',
110
+ 'desc' => __( 'Maximum number of suggestions rows.', DGWT_WCAS_DOMAIN ),
111
+ 'default' => 10,
112
+ ),
113
+ array(
114
+ 'name' => 'min_chars',
115
+ 'label' => __( 'Minimum characters', DGWT_WCAS_DOMAIN ),
116
+ 'type' => 'number',
117
+ 'size' => 'small',
118
+ 'desc' => __( 'Minimum number of characters required to trigger autosuggest.', DGWT_WCAS_DOMAIN ),
119
+ 'default' => 3,
120
+ ),
121
+ array(
122
+ 'name' => 'show_submit_button',
123
+ 'label' => __( 'Show submit button', DGWT_WCAS_DOMAIN ),
124
+ 'type' => 'checkbox',
125
+ 'size' => 'small',
126
+ 'default' => 'off',
127
+ ),
128
+ array(
129
+ 'name' => 'search_submit_text',
130
+ 'label' => __( 'Search submit button text', DGWT_WCAS_DOMAIN ),
131
+ 'type' => 'text',
132
+ 'desc' => __( 'To display a loupe icon leave this field empty.', DGWT_WCAS_DOMAIN ),
133
+ 'default' => __( 'Search', DGWT_WCAS_DOMAIN ),
134
+ ),
135
+ array(
136
+ 'name' => 'search_placeholder',
137
+ 'label' => __( 'Search input placeholder', DGWT_WCAS_DOMAIN ),
138
+ 'type' => 'text',
139
+ 'default' => __( 'Search for products...', DGWT_WCAS_DOMAIN ),
140
+ ),
141
+ array(
142
+ 'name' => 'show_details_box',
143
+ 'label' => __( 'Show details box', DGWT_WCAS_DOMAIN ),
144
+ 'type' => 'checkbox',
145
+ 'size' => 'small',
146
+ 'desc' => __( 'The Details box is an additional container for extended information. The details are changed dynamically when you hover the mouse over one of the suggestions.', DGWT_WCAS_DOMAIN ),
147
+ 'default' => 'off',
148
+ )
149
+ ) ),
150
+ 'dgwt_wcas_advanced' => apply_filters( 'dgwt_wcas_advanced_settings', array(
151
+ array(
152
+ 'name' => 'search_head',
153
+ 'label' => '<h3>' . __( 'Search scope', DGWT_WCAS_DOMAIN ) . '</h3>',
154
+ 'type' => 'head',
155
+ ),
156
+ array(
157
+ 'name' => 'search_in_product_content',
158
+ 'label' => __( 'Search in products content', DGWT_WCAS_DOMAIN ),
159
+ 'type' => 'checkbox',
160
+ 'default' => 'off',
161
+ ),
162
+ array(
163
+ 'name' => 'search_in_product_excerpt',
164
+ 'label' => __( 'Search in products excerpt', DGWT_WCAS_DOMAIN ),
165
+ 'type' => 'checkbox',
166
+ 'default' => 'off',
167
+ ),
168
+ array(
169
+ 'name' => 'search_in_woo_categories',
170
+ 'label' => __( 'Search in products categories', DGWT_WCAS_DOMAIN ),
171
+ 'type' => 'checkbox',
172
+ 'default' => 'on',
173
+ ),
174
+ array(
175
+ 'name' => 'search_in_woo_tags',
176
+ 'label' => __( 'Search in products tags', DGWT_WCAS_DOMAIN ),
177
+ 'type' => 'checkbox',
178
+ 'default' => 'off',
179
+ ),
180
+ array(
181
+ 'name' => 'search_in_product_sku',
182
+ 'label' => __( 'Search in products SKU', DGWT_WCAS_DOMAIN ),
183
+ 'type' => 'checkbox',
184
+ 'default' => 'off',
185
+ ),
186
+ array(
187
+ 'name' => 'product_suggestion_head',
188
+ 'label' => '<h3>' . __( 'Suggestions output', DGWT_WCAS_DOMAIN ) . '</h3>',
189
+ 'type' => 'head',
190
+ ),
191
+ array(
192
+ 'name' => 'show_product_image',
193
+ 'label' => __( 'Show product image', DGWT_WCAS_DOMAIN ),
194
+ 'type' => 'checkbox',
195
+ 'default' => 'off',
196
+ ),
197
+ array(
198
+ 'name' => 'show_product_price',
199
+ 'label' => __( 'Show price', DGWT_WCAS_DOMAIN ),
200
+ 'type' => 'checkbox',
201
+ 'default' => 'off',
202
+ ),
203
+ array(
204
+ 'name' => 'show_product_desc',
205
+ 'label' => __( 'Show product description', DGWT_WCAS_DOMAIN ),
206
+ 'type' => 'checkbox',
207
+ 'default' => 'off',
208
+ ),
209
+ // array(
210
+ // 'name' => 'show_product_sku',
211
+ // 'label' => __( 'Show product SKU', DGWT_WCAS_DOMAIN ),
212
+ // 'type' => 'checkbox',
213
+ // 'default' => 'off',
214
+ // ),
215
+ // array(
216
+ // 'name' => 'show_sale_badge',
217
+ // 'label' => __( 'Show sale badge', DGWT_WCAS_DOMAIN ),
218
+ // 'type' => 'checkbox',
219
+ // 'default' => 'off',
220
+ // ),
221
+ // array(
222
+ // 'name' => 'show_featured_badge',
223
+ // 'label' => __( 'Show featured badge', DGWT_WCAS_DOMAIN ),
224
+ // 'type' => 'checkbox',
225
+ // 'default' => 'off',
226
+ // ),
227
+ ) ),
228
+ 'dgwt_wcas_details_box' => apply_filters( 'dgwt_wcas_details_box_settings', array(
229
+ array(
230
+ 'name' => 'tax_details_tax_head',
231
+ 'label' => '<h3>' . __( 'Category and tag details:', DGWT_WCAS_DOMAIN ) . '</h3>',
232
+ 'type' => 'head',
233
+ ),
234
+ array(
235
+ 'name' => 'show_for_tax',
236
+ 'label' => __( 'Show', DGWT_WCAS_DOMAIN ),
237
+ 'type' => 'select',
238
+ 'options' => array(
239
+ 'all' => __( 'All Product', DGWT_WCAS_DOMAIN ),
240
+ 'featured' => __( 'Featured Products', DGWT_WCAS_DOMAIN ),
241
+ 'onsale' => __( 'On-sale Products', DGWT_WCAS_DOMAIN ),
242
+ ),
243
+ 'default' => 'on',
244
+ ),
245
+ array(
246
+ 'name' => 'orderby_for_tax',
247
+ 'label' => __( 'Order by', DGWT_WCAS_DOMAIN ),
248
+ 'type' => 'select',
249
+ 'options' => array(
250
+ 'date' => __( 'Date', DGWT_WCAS_DOMAIN ),
251
+ 'price' => __( 'Price', DGWT_WCAS_DOMAIN ),
252
+ 'rand' => __( 'Random', DGWT_WCAS_DOMAIN ),
253
+ 'sales' => __( 'Sales', DGWT_WCAS_DOMAIN ),
254
+ ),
255
+ 'default' => 'on',
256
+ ),
257
+ array(
258
+ 'name' => 'order_for_tax',
259
+ 'label' => __( 'Order by', DGWT_WCAS_DOMAIN ),
260
+ 'type' => 'select',
261
+ 'options' => array(
262
+ 'desc' => __( 'DESC', DGWT_WCAS_DOMAIN ),
263
+ 'asc' => __( 'ASC', DGWT_WCAS_DOMAIN ),
264
+ ),
265
+ 'default' => 'desc',
266
+ ),
267
+ array(
268
+ 'name' => 'tax_details_product_other',
269
+ 'label' => '<h3>' . __( 'Other', DGWT_WCAS_DOMAIN ) . '</h3>',
270
+ 'type' => 'head',
271
+ ),
272
+ array(
273
+ 'name' => 'details_box_position',
274
+ 'label' => __( 'Details box position', DGWT_WCAS_DOMAIN ),
275
+ 'type' => 'select',
276
+ 'desc' => __( 'If your search form is very close to the right window screen, then select left.', DGWT_WCAS_DOMAIN ),
277
+ 'options' => array(
278
+ 'left' => __( 'Left', DGWT_WCAS_DOMAIN ),
279
+ 'right' => __( 'Right', DGWT_WCAS_DOMAIN ),
280
+ ),
281
+ 'default' => 'right',
282
+ )
283
+ ) ),
284
+ 'dgwt_wcas_style' => apply_filters( 'dgwt_wcas_style_settings', array(
285
+ array(
286
+ 'name' => 'search_form',
287
+ 'label' => '<h3>' . __( 'Search form', DGWT_WCAS_DOMAIN ) . '</h3>',
288
+ 'type' => 'head',
289
+ ),
290
+ array(
291
+ 'name' => 'bg_input_color',
292
+ 'label' => __( 'Search input background', DGWT_WCAS_DOMAIN ),
293
+ 'type' => 'color',
294
+ 'default' => '',
295
+ ),
296
+ array(
297
+ 'name' => 'text_input_color',
298
+ 'label' => __( 'Search input text', DGWT_WCAS_DOMAIN ),
299
+ 'type' => 'color',
300
+ 'default' => '',
301
+ ),
302
+ array(
303
+ 'name' => 'border_input_color',
304
+ 'label' => __( 'Search input border', DGWT_WCAS_DOMAIN ),
305
+ 'type' => 'color',
306
+ 'default' => '',
307
+ ),
308
+ array(
309
+ 'name' => 'bg_submit_color',
310
+ 'label' => __( 'Search submit background', DGWT_WCAS_DOMAIN ),
311
+ 'type' => 'color',
312
+ 'default' => '',
313
+ ),
314
+ array(
315
+ 'name' => 'text_submit_color',
316
+ 'label' => __( 'Search submit text', DGWT_WCAS_DOMAIN ),
317
+ 'type' => 'color',
318
+ 'default' => '',
319
+ ),
320
+ array(
321
+ 'name' => 'syggestions_style_head',
322
+ 'label' => '<h3>' . __( 'Suggestions', DGWT_WCAS_DOMAIN ) . '</h3>',
323
+ 'type' => 'head',
324
+ ),
325
+ array(
326
+ 'name' => 'sug_bg_color',
327
+ 'label' => __( 'Suggestion background', DGWT_WCAS_DOMAIN ),
328
+ 'type' => 'color',
329
+ 'default' => '',
330
+ ),
331
+ array(
332
+ 'name' => 'sug_hover_color',
333
+ 'label' => __( 'Suggestion selected', DGWT_WCAS_DOMAIN ),
334
+ 'type' => 'color',
335
+ 'default' => '',
336
+ ),
337
+ array(
338
+ 'name' => 'sug_text_color',
339
+ 'label' => __( 'Text color', DGWT_WCAS_DOMAIN ),
340
+ 'type' => 'color',
341
+ 'default' => '',
342
+ ),
343
+ array(
344
+ 'name' => 'sug_highlight_color',
345
+ 'label' => __( 'Highlight color', DGWT_WCAS_DOMAIN ),
346
+ 'type' => 'color',
347
+ 'default' => '',
348
+ ),
349
+ array(
350
+ 'name' => 'sug_border_color',
351
+ 'label' => __( 'Border color', DGWT_WCAS_DOMAIN ),
352
+ 'type' => 'color',
353
+ 'default' => '',
354
+ ),
355
+ array(
356
+ 'name' => 'preloader',
357
+ 'label' => '<h3>' . __( 'Preloader', DGWT_WCAS_DOMAIN ) . '</h3>',
358
+ 'type' => 'head',
359
+ ),
360
+ array(
361
+ 'name' => 'show_preloader',
362
+ 'label' => __( 'Show preloader', DGWT_WCAS_DOMAIN ),
363
+ 'type' => 'checkbox',
364
+ 'default' => 'on',
365
+ ),
366
+ array(
367
+ 'name' => 'preloader_url',
368
+ 'label' => __( 'Upload preloader image', DGWT_WCAS_DOMAIN ),
369
+ 'type' => 'file',
370
+ 'default' => '',
371
+ ),
372
+ ) )
373
+ );
374
+
375
+
376
+ return $settings_fields;
377
+ }
378
+
379
+ /*
380
+ * Print optin value
381
+ *
382
+ * @param string $option_key
383
+ * @param string $default default value if option not exist
384
+ *
385
+ * @return string
386
+ */
387
+
388
+ public function get_opt( $option_key, $default = '' ) {
389
+
390
+ $value = '';
391
+
392
+ if ( is_string( $option_key ) && !empty( $option_key ) ) {
393
+
394
+ if ( array_key_exists( $option_key, $this->opt ) ) {
395
+ $value = $this->opt[ $option_key ];
396
+ } else {
397
+
398
+ // Catch default
399
+ foreach ( $this->settings_fields() as $section ) {
400
+ foreach ( $section as $field ) {
401
+ if ( $field[ 'name' ] === $option_key && isset( $field[ 'default' ] ) ) {
402
+ $value = $field[ 'default' ];
403
+ }
404
+ }
405
+ }
406
+ }
407
+ }
408
+
409
+ if ( empty( $value ) && !empty( $default ) ) {
410
+ $value = $default;
411
+ }
412
+
413
+ return apply_filters( 'dgwt_wcas_return_option_value', $value, $option_key );
414
+ }
415
+
416
+ /**
417
+ * Handles output of the settings
418
+ */
419
+ public static function output() {
420
+
421
+ $settings = DGWT_WCAS()->settings->settings_api;
422
+
423
+ include_once DGWT_WCAS_DIR . 'includes/admin/views/settings.php';
424
+ }
425
+
426
+ }
427
+
428
+ /*
429
+ * Disable details box setting tab if the option id rutns off
430
+ */
431
+ add_filter( 'dgwt_wcas_settings_sections', 'dgwt_wcas_hide_settings_detials_tab' );
432
+
433
+ function dgwt_wcas_hide_settings_detials_tab( $sections ) {
434
+
435
+ if ( DGWT_WCAS()->settings->get_opt( 'show_details_box' ) !== 'on' && is_array( $sections ) ) {
436
+
437
+ $i = 0;
438
+ foreach ( $sections as $section ) {
439
+
440
+ if ( isset( $section[ 'id' ] ) && $section[ 'id' ] === 'dgwt_wcas_details_box' ) {
441
+ unset( $sections[ $i ] );
442
+
443
+ }
444
+
445
+ $i++;
446
+ }
447
+ }
448
+
449
+ return $sections;
450
+ }
includes/admin/views/how-to-use.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+
2
+ <h4><?php _e( 'There are two easy ways to display the search form', DGWT_WCAS_DOMAIN ); ?>: </h4>
3
+ <p>1. <?php printf(__( 'Use shorcode %s', DGWT_WCAS_DOMAIN ), '<code>[wcas-search-form]</code>'); ?></p>
4
+ <p>2. <?php printf(__( 'Go to the %s and choose "Woo Ajax Search"', DGWT_WCAS_DOMAIN ), '<a href="'. admin_url('widgets.php').'">' . __( 'Widgets Screen', DGWT_WCAS_DOMAIN ) . '</a>') ?>
includes/admin/views/settings.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Zakoncz, jeżeli plik jest załadowany bezpośrednio
3
+ if ( !defined( 'ABSPATH' ) )
4
+ exit;
5
+ ?>
6
+
7
+ <div class="wrap">
8
+
9
+ <h2><?php _e( 'Ajax Search for WooCommerce', DGWT_WCAS_DOMAIN ); ?></h2>
10
+
11
+ <?php $settings->show_navigation(); ?>
12
+ <?php $settings->show_forms(); ?>
13
+
14
+ </div>
includes/class-result-details.php ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( !defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
+
8
+ class DGWT_WCAS_Result_Details {
9
+
10
+ function __construct() {
11
+
12
+ // Searched result details ajax action
13
+ if ( DGWT_WCAS_WC_AJAX_ENDPOINT ) {
14
+ add_action( 'wc_ajax_' . DGWT_WCAS_RESULT_DETAILS_ACTION, array( $this, 'get_result_details' ) );
15
+ } else {
16
+ add_action( 'wp_ajax_nopriv_' . DGWT_WCAS_RESULT_DETAILS_ACTION, array( $this, 'get_result_details' ) );
17
+ add_action( 'wp_ajax_' . DGWT_WCAS_RESULT_DETAILS_ACTION, array( $this, 'get_result_details' ) );
18
+ }
19
+ }
20
+
21
+ /*
22
+ * Get searched result details
23
+ */
24
+
25
+ public function get_result_details() {
26
+
27
+ $output = array();
28
+ $html = '';
29
+ $suggestion = '';
30
+
31
+ // Sugestion value
32
+ if ( isset( $_REQUEST[ 'value' ] ) && !empty( $_REQUEST[ 'value' ] ) ) {
33
+ $suggestion = sanitize_text_field( $_REQUEST[ 'value' ] );
34
+ }
35
+
36
+ // Get product details
37
+ if ( isset( $_REQUEST[ 'post_id' ] ) && is_numeric( $_REQUEST[ 'post_id' ] ) ) {
38
+
39
+ $product_id = absint( $_REQUEST[ 'post_id' ] );
40
+ if ( DGWT_WCAS_WOO_PRODUCT_POST_TYPE === get_post_type( $product_id ) ) {
41
+ $html = $this->get_product_details( $product_id );
42
+ }
43
+ }
44
+
45
+ // Get taxonomy details
46
+ if ( isset( $_REQUEST[ 'term_id' ] ) && isset( $_REQUEST[ 'taxonomy' ] ) ) {
47
+
48
+ $term_id = is_numeric( $_REQUEST[ 'term_id' ] ) && $_REQUEST[ 'term_id' ] > 0 ? absint( $_REQUEST[ 'term_id' ] ) : false;
49
+
50
+ if ( $term_id !== false ) {
51
+
52
+ $html = '';
53
+
54
+ switch ( $_REQUEST[ 'taxonomy' ] ) {
55
+ case DGWT_WCAS_WOO_PRODUCT_CATEGORY:
56
+ $html = $this->get_taxonomy_details( $term_id, DGWT_WCAS_WOO_PRODUCT_CATEGORY, $suggestion );
57
+ break;
58
+ case DGWT_WCAS_WOO_PRODUCT_TAG:
59
+ $html = $this->get_taxonomy_details( $term_id, DGWT_WCAS_WOO_PRODUCT_TAG, $suggestion );
60
+ break;
61
+ }
62
+ }
63
+ }
64
+
65
+
66
+
67
+ $output[ 'details' ] = $html;
68
+
69
+ echo json_encode( $output );
70
+ die();
71
+ }
72
+
73
+ /*
74
+ * Prepare products details to the ajax output
75
+ *
76
+ * @param int $product_id
77
+ * @param string $value Suggestion value
78
+ *
79
+ * @return string HTML
80
+ */
81
+
82
+ private function get_product_details( $product_id ) {
83
+
84
+ $html = '';
85
+
86
+ $product = new WC_Product( $product_id );
87
+
88
+ if ( empty( $product->post ) ) {
89
+ return;
90
+ }
91
+
92
+ $details = array(
93
+ 'id' => $product->id,
94
+ 'desc' => '',
95
+ );
96
+
97
+
98
+ // Get product desc
99
+ $details[ 'desc' ] = dgwt_wcas_get_product_desc( $product, 500);
100
+
101
+
102
+ ob_start();
103
+ include_once DGWT_WCAS_DIR . 'includes/tmpl/single-product.php';
104
+ $html = ob_get_clean();
105
+
106
+
107
+ return $html;
108
+ }
109
+
110
+ /*
111
+ * Prepare category details to the ajax output
112
+ *
113
+ * @param int $term_id
114
+ * @param string taxonomy
115
+ * @param string $suggestion Suggestion value
116
+ *
117
+ * @return string HTML
118
+ */
119
+
120
+ private function get_taxonomy_details( $term_id, $taxonomy, $suggestion ) {
121
+
122
+ $html = '';
123
+ $title = '';
124
+
125
+ ob_start();
126
+
127
+ $query_args = $this->get_taxonomy_query_args();
128
+
129
+ // Serach with specific category
130
+ $query_args[ 'tax_query' ][] = array(
131
+ 'taxonomy' => $taxonomy,
132
+ 'field' => 'id',
133
+ 'terms' => $term_id,
134
+ 'include_children' => true,
135
+ );
136
+
137
+ $products = new WP_Query( $query_args );
138
+
139
+ if ( $products->have_posts() ) {
140
+
141
+
142
+
143
+ // Details box title
144
+ $title .= '<span class="dgwt-wcas-datails-title">';
145
+ $title .= '<span class="dgwt-wcas-details-title-tax">';
146
+ if ( DGWT_WCAS_WOO_PRODUCT_CATEGORY === $taxonomy ) {
147
+ $title .= __( 'Category', DGWT_WCAS_DOMAIN ) . ': ';
148
+ } else {
149
+ $title .= __( 'Tag', DGWT_WCAS_DOMAIN ) . ': ';
150
+ }
151
+ $title .= '</span>';
152
+ $title .= $suggestion;
153
+ $title .= '</span>';
154
+
155
+
156
+ echo '<div class="dgwt-wcas-details-inner">';
157
+ echo '<div class="dgwt-wcas-products-in-cat">';
158
+
159
+ echo!empty( $title ) ? $title : '';
160
+
161
+ while ( $products->have_posts() ) {
162
+ $products->the_post();
163
+
164
+ $product = new WC_Product( get_the_ID() );
165
+
166
+ include DGWT_WCAS_DIR . 'includes/tmpl/single-product-tax.php';
167
+ }
168
+
169
+ echo '</div>';
170
+ echo '</div>';
171
+ }
172
+
173
+ wp_reset_postdata();
174
+
175
+
176
+ $html = ob_get_clean();
177
+
178
+
179
+ return $html;
180
+ }
181
+
182
+ /*
183
+ * Taxonomy query args
184
+ * Get vars from settings
185
+ */
186
+
187
+ private function get_taxonomy_query_args() {
188
+
189
+ $show = sanitize_title( DGWT_WCAS()->settings->get_opt( 'show_for_tax' ) );
190
+ $orderby = sanitize_title( DGWT_WCAS()->settings->get_opt( 'orderby_for_tax' ) );
191
+ $order = sanitize_title( DGWT_WCAS()->settings->get_opt( 'order_for_tax' ) );
192
+
193
+ $query_args = array(
194
+ 'posts_per_page' => 4,
195
+ 'post_status' => 'publish',
196
+ 'post_type' => 'product',
197
+ 'no_found_rows' => 1,
198
+ 'order' => $order,
199
+ 'meta_query' => array()
200
+ );
201
+
202
+ // @TODO Impelement show_hide and hide_free options
203
+ //
204
+ // if ( empty( $instance[ 'show_hidden' ] ) ) {
205
+ // $query_args[ 'meta_query' ][] = WC()->query->visibility_meta_query();
206
+ // $query_args[ 'post_parent' ] = 0;
207
+ // }
208
+ //
209
+ // if ( !empty( $instance[ 'hide_free' ] ) ) {
210
+ // $query_args[ 'meta_query' ][] = array(
211
+ // 'key' => '_price',
212
+ // 'value' => 0,
213
+ // 'compare' => '>',
214
+ // 'type' => 'DECIMAL',
215
+ // );
216
+ // }
217
+
218
+ $query_args[ 'meta_query' ][] = WC()->query->stock_status_meta_query();
219
+ $query_args[ 'meta_query' ] = array_filter( $query_args[ 'meta_query' ] );
220
+
221
+ switch ( $show ) {
222
+ case 'featured' :
223
+ $query_args[ 'meta_query' ][] = array(
224
+ 'key' => '_featured',
225
+ 'value' => 'yes'
226
+ );
227
+ break;
228
+ case 'onsale' :
229
+ $product_ids_on_sale = wc_get_product_ids_on_sale();
230
+ $product_ids_on_sale[] = 0;
231
+ $query_args[ 'post__in' ] = $product_ids_on_sale;
232
+ break;
233
+ }
234
+
235
+ switch ( $orderby ) {
236
+ case 'price' :
237
+ $query_args[ 'meta_key' ] = '_price';
238
+ $query_args[ 'orderby' ] = 'meta_value_num';
239
+ break;
240
+ case 'rand' :
241
+ $query_args[ 'orderby' ] = 'rand';
242
+ break;
243
+ case 'sales' :
244
+ $query_args[ 'meta_key' ] = 'total_sales';
245
+ $query_args[ 'orderby' ] = 'meta_value_num';
246
+ break;
247
+ default :
248
+ $query_args[ 'orderby' ] = 'date';
249
+ }
250
+
251
+
252
+ return $query_args;
253
+ }
254
+
255
+ }
256
+
257
+ ?>
includes/class-search.php ADDED
@@ -0,0 +1,389 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( !defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
+
8
+ class DGWT_WCAS_Search {
9
+ /*
10
+ * Suggestions limit
11
+ * int
12
+ */
13
+
14
+ private $limit;
15
+
16
+ /*
17
+ * Description limit
18
+ * int
19
+ */
20
+ private $desc_limit = 130;
21
+
22
+ /*
23
+ * Empty slots
24
+ * int
25
+ */
26
+ private $slots;
27
+
28
+ function __construct() {
29
+
30
+ $this->limit = absint( DGWT_WCAS()->settings->get_opt( 'suggestions_limit', 10 ) );
31
+ $this->slots = $this->limit; // Free slots for the results. Default 10
32
+
33
+ add_filter( 'posts_search', array( $this, 'search_filters' ), 501, 2 );
34
+ add_filter( 'pre_get_posts', array( $this, 'change_wp_search_size' ), 500 );
35
+
36
+
37
+ // Search results ajax action
38
+ if ( DGWT_WCAS_WC_AJAX_ENDPOINT ) {
39
+ add_action( 'wc_ajax_' . DGWT_WCAS_SEARCH_ACTION, array( $this, 'get_search_results' ) );
40
+ } else {
41
+ add_action( 'wp_ajax_nopriv_' . DGWT_WCAS_SEARCH_ACTION, array( $this, 'get_search_results' ) );
42
+ add_action( 'wp_ajax_' . DGWT_WCAS_SEARCH_ACTION, array( $this, 'get_search_results' ) );
43
+ }
44
+ }
45
+
46
+ /*
47
+ * Get search results via ajax
48
+ */
49
+
50
+ public function get_search_results() {
51
+ global $woocommerce;
52
+
53
+ if ( !defined( 'DGWT_WCAS_AJAX' ) ) {
54
+ define( 'DGWT_WCAS_AJAX', true );
55
+ }
56
+
57
+ $output = array();
58
+ $results = array();
59
+ $keyword = sanitize_text_field( $_REQUEST[ 'dgwt_wcas_keyword' ] );
60
+
61
+
62
+ //@todo Get results from cache
63
+
64
+ /* SEARCH IN WOO CATEGORIES */
65
+ if ( DGWT_WCAS()->settings->get_opt( 'search_in_woo_categories' ) === 'on' ) {
66
+
67
+ $results = array_merge( $this->get_categories( $keyword ), $results );
68
+
69
+ // Update slots
70
+ $this->slots = $this->slots - count( $results );
71
+ } /* END SEARCH IN WOO CATEGORIES */
72
+
73
+
74
+ /* SEARCH IN WOO TAGS */
75
+ if ( $this->slots > 0 ) {
76
+
77
+ if ( DGWT_WCAS()->settings->get_opt( 'search_in_woo_tags' ) === 'on' ) {
78
+
79
+ $results = array_merge( $this->get_tags( $keyword ), $results );
80
+
81
+ // Update slots
82
+ $this->slots = $this->slots - count( $results );
83
+ }
84
+ }/* END SEARCH IN WOO TAGS */
85
+
86
+
87
+ // Continue searching in products if there are room in the slots
88
+ /* SEARCH IN PRODUCTS */
89
+ if ( $this->slots > 0 ) {
90
+ $ordering_args = $woocommerce->query->get_catalog_ordering_args( 'title', 'asc' );
91
+
92
+ $args = array(
93
+ 's' => $keyword,
94
+ 'post_type' => DGWT_WCAS_WOO_PRODUCT_POST_TYPE,
95
+ 'post_status' => 'publish',
96
+ 'ignore_sticky_posts' => 1,
97
+ 'orderby' => $ordering_args[ 'orderby' ],
98
+ 'order' => $ordering_args[ 'order' ],
99
+ 'suppress_filters' => false,
100
+ 'meta_query' => array(
101
+ array(
102
+ 'key' => '_visibility',
103
+ 'value' => array( 'search', 'visible' ),
104
+ 'compare' => 'IN'
105
+ )
106
+ )
107
+ );
108
+
109
+
110
+ $products = get_posts( $args );
111
+
112
+ if ( !empty( $products ) ) {
113
+
114
+ foreach ( $products as $post ) {
115
+ $product = wc_get_product( $post );
116
+
117
+ $r = array(
118
+ 'post_id' => $product->id,
119
+ 'value' => strip_tags( $product->get_title() ),
120
+ 'url' => $product->get_permalink(),
121
+ );
122
+
123
+ // Get thumb HTML
124
+ if ( DGWT_WCAS()->settings->get_opt( 'show_product_image' ) === 'on' ) {
125
+ $r[ 'thumb_html' ] = $product->get_image( array( 60, 60 ) );
126
+ }
127
+
128
+ // Get price
129
+ if ( DGWT_WCAS()->settings->get_opt( 'show_product_price' ) === 'on' ) {
130
+ $r[ 'price' ] = $product->get_price_html();
131
+ }
132
+
133
+ // Get description
134
+ if ( DGWT_WCAS()->settings->get_opt( 'show_product_desc' ) === 'on' ) {
135
+ if ( DGWT_WCAS()->settings->get_opt( 'show_details_box' ) === 'on' ) {
136
+ $this->desc_limit = 60;
137
+ }
138
+ $r[ 'desc' ] = dgwt_wcas_get_product_desc( $product->id, $this->desc_limit );
139
+ }
140
+
141
+ // Is on sale
142
+ if ( DGWT_WCAS()->settings->get_opt( 'show_sale_badge' ) === 'on' ) {
143
+ $r[ 'on_sale' ] = $product->is_on_sale();
144
+ }
145
+
146
+ // Is featured
147
+ if ( DGWT_WCAS()->settings->get_opt( 'show_featured_badge' ) === 'on' ) {
148
+ $r[ 'featured' ] = $product->is_featured();
149
+ }
150
+
151
+ $results[] = apply_filters( 'dgwt_wcas_products_suggestions', $r, $product );
152
+ }
153
+ }
154
+ wp_reset_postdata();
155
+ } /* END SEARCH IN PRODUCTS */
156
+
157
+
158
+
159
+ // Show nothing on empty results
160
+ //@todo show 'No results' as option
161
+ if ( empty( $results ) ) {
162
+
163
+ // $results[] = array(
164
+ // 'post_id' => - 1,
165
+ // 'value' => __( 'No results', DGWT_WCAS_DOMAIN ),
166
+ // 'url' => '',
167
+ // );
168
+ }
169
+
170
+ //@todo Add results to the wp cache
171
+
172
+ $output[ 'suggestions' ] = $results;
173
+
174
+ echo json_encode( $output );
175
+ die();
176
+ }
177
+
178
+ /*
179
+ * Search for matching category
180
+ *
181
+ * @param string $keyword
182
+ *
183
+ * @return array
184
+ */
185
+
186
+ public function get_categories( $keyword ) {
187
+
188
+ $results = array();
189
+
190
+ $args = array(
191
+ 'taxonomy' => DGWT_WCAS_WOO_PRODUCT_CATEGORY
192
+ );
193
+
194
+ $product_categories = get_terms( DGWT_WCAS_WOO_PRODUCT_CATEGORY, $args );
195
+
196
+ // Compare keyword and term name
197
+ $i = 0;
198
+ foreach ( $product_categories as $cat ) {
199
+
200
+ if ( $i < $this->limit ) {
201
+
202
+ $pos = strpos( strtolower( $cat->name ), strtolower( $keyword ) );
203
+
204
+ if ( $pos !== false ) {
205
+ $results[ $i ] = array(
206
+ 'term_id' => $cat->term_id,
207
+ 'taxonomy' => DGWT_WCAS_WOO_PRODUCT_CATEGORY,
208
+ 'value' => preg_replace( sprintf( "/(%s)/", $keyword ), "$1", $cat->name ),
209
+ 'url' => get_term_link( $cat, DGWT_WCAS_WOO_PRODUCT_CATEGORY ),
210
+ 'parents' => ''
211
+ );
212
+
213
+
214
+ // Add category parents info
215
+ $parents = $this->get_taxonomy_parent_string( $cat->term_id, DGWT_WCAS_WOO_PRODUCT_CATEGORY, array(), array( $cat->term_id ) );
216
+
217
+ if ( !empty( $parents ) ) {
218
+
219
+ $results[ $i ][ 'parents' ] = sprintf( ' <em>%s <b>%s</b></em>', __( 'in', DGWT_WCAS_DOMAIN ), mb_substr( $parents, 0, -3 ) );
220
+ }
221
+ }
222
+ }
223
+
224
+ $i++;
225
+ }
226
+
227
+ return $results;
228
+ }
229
+
230
+ /*
231
+ * Extend research in the Woo tags
232
+ *
233
+ * @param strong $keyword
234
+ *
235
+ * @return array
236
+ */
237
+
238
+ public function get_tags( $keyword ) {
239
+
240
+ $results = array();
241
+
242
+ $args = array(
243
+ 'taxonomy' => DGWT_WCAS_WOO_PRODUCT_TAG
244
+ );
245
+
246
+ $product_tags = get_terms( DGWT_WCAS_WOO_PRODUCT_TAG, $args );
247
+
248
+ // Compare keyword and term name
249
+ $i = 0;
250
+ foreach ( $product_tags as $tag ) {
251
+
252
+ if ( $i < $this->limit ) {
253
+
254
+ $pos = strpos( strtolower( $tag->name ), strtolower( $keyword ) );
255
+
256
+ if ( $pos !== false ) {
257
+ $results[ $i ] = array(
258
+ 'term_id' => $tag->term_id,
259
+ 'taxonomy' => DGWT_WCAS_WOO_PRODUCT_TAG,
260
+ 'value' => preg_replace( sprintf( "/(%s)/", $keyword ), "$1", $tag->name ),
261
+ 'url' => get_term_link( $tag, DGWT_WCAS_WOO_PRODUCT_TAG ),
262
+ 'parents' => ''
263
+ );
264
+
265
+ // Add taxonomy parents info
266
+ $parents = $this->get_taxonomy_parent_string( $tag->term_id, DGWT_WCAS_WOO_PRODUCT_TAG, array(), array( $tag->term_id ) );
267
+
268
+ if ( !empty( $parents ) ) {
269
+
270
+ $results[ $i ][ 'parents' ] = sprintf( ' <em>%s <b>%s</b></em>', __( 'in', DGWT_WCAS_DOMAIN ), mb_substr( $parents, 0, -3 ) );
271
+ }
272
+ }
273
+ }
274
+
275
+ $i++;
276
+ }
277
+
278
+ return $results;
279
+ }
280
+
281
+ /*
282
+ * Set search product limit
283
+ */
284
+
285
+ public function change_wp_search_size( $query ) {
286
+
287
+ if ( defined( 'DGWT_WCAS_AJAX' ) ) {
288
+ if ( $query->is_search )
289
+ $query->query_vars[ 'posts_per_page' ] = $this->slots;
290
+ }
291
+
292
+ return $query;
293
+ }
294
+
295
+ /*
296
+ * Search only in products titles
297
+ *
298
+ * @param string $search SQL
299
+ * @param object $wp_query
300
+ *
301
+ * @return string prepared SQL
302
+ */
303
+
304
+ public function search_filters( $search, &$wp_query ) {
305
+ global $wpdb;
306
+
307
+ if ( empty( $search ) ) {
308
+ return $search; // skip processing - no search term in query
309
+ }
310
+
311
+ $q = $wp_query->query_vars;
312
+
313
+ if ( $q[ 'post_type' ] !== DGWT_WCAS_WOO_PRODUCT_POST_TYPE ) {
314
+ return $search; // skip processing - on Woo products
315
+ }
316
+
317
+ $n = !empty( $q[ 'exact' ] ) ? '' : '%';
318
+
319
+ $search = $searchand = '';
320
+
321
+ foreach ( (array) $q[ 'search_terms' ] as $term ) {
322
+ $term = esc_sql( $wpdb->esc_like( $term ) );
323
+
324
+ $search .= "{$searchand} (";
325
+
326
+ // Search in title
327
+ $search .= "($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
328
+
329
+ // Search in content
330
+ if ( DGWT_WCAS()->settings->get_opt( 'search_in_product_content' ) === 'on' ) {
331
+ $search .= " OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}')";
332
+ }
333
+
334
+ // Search in excerpt
335
+ if ( DGWT_WCAS()->settings->get_opt( 'search_in_product_excerpt' ) === 'on' ) {
336
+ $search .= " OR ($wpdb->posts.post_excerpt LIKE '{$n}{$term}{$n}')";
337
+ }
338
+
339
+ $search .= ")";
340
+
341
+ $searchand = ' AND ';
342
+ }
343
+
344
+ if ( !empty( $search ) ) {
345
+ $search = " AND ({$search}) ";
346
+ if ( !is_user_logged_in() )
347
+ $search .= " AND ($wpdb->posts.post_password = '') ";
348
+ }
349
+
350
+ return $search;
351
+ }
352
+
353
+ /*
354
+ * Get taxonomy parent
355
+ *
356
+ * @param int $term_id
357
+ * @param string $taxonomy
358
+ *
359
+ * @return string
360
+ */
361
+
362
+ private function get_taxonomy_parent_string( $term_id, $taxonomy, $visited = array(), $exclude = array() ) {
363
+
364
+ $chain = '';
365
+ $separator = ' > ';
366
+
367
+ $parent = get_term( $term_id, $taxonomy );
368
+
369
+ if ( empty( $parent ) || !isset( $parent->name ) ) {
370
+ return '';
371
+ }
372
+
373
+ $name = $parent->name;
374
+
375
+ if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {
376
+ $visited[] = $parent->parent;
377
+ $chain .= $this->get_taxonomy_parent_string( $parent->parent, $taxonomy, $visited );
378
+ }
379
+
380
+ if ( !in_array( $parent->term_id, $exclude ) ) {
381
+ $chain .= $name . $separator;
382
+ }
383
+
384
+ return $chain;
385
+ }
386
+
387
+ }
388
+
389
+ ?>
includes/functions.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+
8
+ /*
9
+ * Display search form
10
+ *
11
+ * @param array args
12
+ * @return string
13
+ */
14
+
15
+ function dgwt_wcas_get_search_form( $args = array() ) {
16
+
17
+ // Enqueue required scripts
18
+ wp_enqueue_script( array(
19
+ 'woocommerce-general',
20
+ 'jquery-dgwt-wcas',
21
+ ) );
22
+
23
+ ob_start();
24
+ include DGWT_WCAS_DIR . 'includes/tmpl/search-form.php';
25
+ $html = ob_get_clean();
26
+
27
+ return $html;
28
+ }
29
+
30
+ /*
31
+ * Return ajax loader URL
32
+ *
33
+ * @param array args
34
+ * @return string
35
+ */
36
+
37
+ function dgwt_wcas_get_admin_ajax_url( $args = array() ) {
38
+
39
+ $protocol = isset( $_SERVER[ 'HTTPS' ] ) ? 'https://' : 'http://';
40
+ $ajax_url = admin_url( 'admin-ajax.php', $protocol );
41
+
42
+ return add_query_arg( $args, $ajax_url );
43
+ }
44
+
45
+ /*
46
+ * Cut string
47
+ *
48
+ * @param string $string
49
+ * @param int $length
50
+ *
51
+ * @return string
52
+ */
53
+
54
+ function dgwt_wcas_str_cut( $string, $length = 40 ) {
55
+
56
+ $string = strip_tags( $string );
57
+
58
+ if ( strlen( $string ) > $length ) {
59
+ $title = mb_substr( $string, 0, $length, 'utf-8' ) . '...';
60
+ } else {
61
+ $title = $string;
62
+ }
63
+ return $title;
64
+ }
65
+
66
+ /*
67
+ * Add css classes to search form
68
+ *
69
+ * @param array $args
70
+ * @return string
71
+ */
72
+
73
+ function dgwt_wcas_search_css_classes( $args = array() ) {
74
+
75
+ $classes = array();
76
+
77
+ if ( DGWT_WCAS()->settings->get_opt( 'show_details_box' ) === 'on' ) {
78
+ $classes[] = 'dgwt-wcas-is-detail-box';
79
+ }
80
+
81
+ if ( DGWT_WCAS()->settings->get_opt( 'show_submit_button' ) !== 'on'){
82
+ $classes[] = 'dgwt-wcas-no-submit';
83
+ }
84
+
85
+ if ( isset( $args[ 'class' ] ) && !empty( $args[ 'class' ] ) ) {
86
+ $classes[] = esc_html( $args[ 'class' ] );
87
+ }
88
+
89
+ if ( is_rtl() ) {
90
+ $classes[] = 'dgwt_wcas_rtl';
91
+ }
92
+
93
+ return implode( ' ', $classes );
94
+ }
95
+
96
+ /*
97
+ * Add custom preloader to input
98
+ */
99
+ add_action( 'wp_head', 'dgwt_wcas_custom_preloader_css' );
100
+
101
+ function dgwt_wcas_custom_preloader_css() {
102
+
103
+ $url = DGWT_WCAS()->settings->get_opt( 'preloader_url' );
104
+
105
+ if ( !empty( $url ) ) {
106
+ ?>
107
+ <style>
108
+ .dgwt-wcas-inner-preloader {
109
+ background-image: url('<?php echo esc_url( $url ); ?>');
110
+ }
111
+ </style>
112
+ <?php
113
+ }
114
+ }
115
+
116
+ /*
117
+ * Print loupe SVG ico
118
+ */
119
+
120
+ function dgwt_wcas_print_ico_loupe() {
121
+ ?>
122
+ <svg version="1.1" class="dgwt-wcas-ico-loupe" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
123
+ viewBox="0 0 51.539 51.361" enable-background="new 0 0 51.539 51.361" xml:space="preserve">
124
+ <path d="M51.539,49.356L37.247,35.065c3.273-3.74,5.272-8.623,5.272-13.983c0-11.742-9.518-21.26-21.26-21.26
125
+ S0,9.339,0,21.082s9.518,21.26,21.26,21.26c5.361,0,10.244-1.999,13.983-5.272l14.292,14.292L51.539,49.356z M2.835,21.082
126
+ c0-10.176,8.249-18.425,18.425-18.425s18.425,8.249,18.425,18.425S31.436,39.507,21.26,39.507S2.835,31.258,2.835,21.082z"/>
127
+ </svg>
128
+ <?php
129
+ }
130
+
131
+ /*
132
+ * Get product desc
133
+ *
134
+ * @param int $product product object or The post ID
135
+ * @param int $length description length
136
+ *
137
+ * @return string
138
+ */
139
+
140
+ function dgwt_wcas_get_product_desc( $product, $length = 130 ) {
141
+
142
+ if ( is_numeric( $product ) ) {
143
+ $product = new WC_Product( $product );
144
+ }
145
+
146
+ $output = '';
147
+
148
+ if ( is_object( $product ) && isset( $product->post ) ) {
149
+
150
+ if ( !empty( $product->post->post_excerpt ) ) {
151
+ $output = dgwt_wcas_str_cut( wp_strip_all_tags( $product->post->post_excerpt ), $length );
152
+ } else {
153
+ if ( !empty( $product->post->post_content ) ) {
154
+ $output = dgwt_wcas_str_cut( wp_strip_all_tags( $product->post->post_content ), $length );
155
+ }
156
+ }
157
+ }
158
+ return $output;
159
+ }
160
+
161
+ /*
162
+ * Return HTML for the setting section "How to use?"
163
+ *
164
+ * @return string HTML
165
+ */
166
+
167
+ function dgwt_wcas_how_to_use_html() {
168
+
169
+ $html = '';
170
+
171
+ ob_start();
172
+
173
+ include DGWT_WCAS_DIR . 'includes/admin/views/how-to-use.php';
174
+
175
+ $html .= ob_get_clean();
176
+
177
+ return $html;
178
+ }
includes/install.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Installation related functions and actions.
5
+ *
6
+ */
7
+ // Exit if accessed directly
8
+ if ( !defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ class DGWT_WCAS_Install {
13
+
14
+ /**
15
+ * Hook in tabs.
16
+ */
17
+ public static function init() {
18
+
19
+ add_action( 'admin_init', array( __CLASS__, 'check_version' ), 5 );
20
+ }
21
+
22
+ /**
23
+ * Install
24
+ */
25
+ public static function install() {
26
+
27
+
28
+ if ( !defined( 'DGWT_WCAS_INSTALLING' ) ) {
29
+ define( 'DGWT_WCAS_INSTALLING', true );
30
+ }
31
+
32
+ self::create_options();
33
+ self::create_cron_jobs();
34
+
35
+ // Update plugin version
36
+ update_option( 'dgwt_wcas_version', DGWT_WCAS_VERSION );
37
+
38
+ }
39
+
40
+ /**
41
+ * Default options
42
+ */
43
+ private static function create_options() {
44
+
45
+ global $dgwt_wcas_settings;
46
+
47
+ $sections = DGWT_WCAS()->settings->settings_fields();
48
+
49
+ $settings = array();
50
+
51
+ if ( is_array( $sections ) && !empty( $sections ) ) {
52
+ foreach ( $sections as $options ) {
53
+
54
+ if ( is_array( $options ) && !empty( $options ) ) {
55
+
56
+ foreach ( $options as $option ) {
57
+
58
+ if ( isset( $option[ 'name' ] ) && !isset( $dgwt_wcas_settings[ $option[ 'name' ] ] ) ) {
59
+
60
+ $settings[ $option[ 'name' ] ] = isset( $option[ 'default' ] ) ? $option[ 'default' ] : '';
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ $update_options = array_merge( $settings, $dgwt_wcas_settings );
68
+
69
+ update_option( DGWT_WCAS_SETTINGS_KEY, $update_options );
70
+ }
71
+
72
+ /**
73
+ * Create cron jobs (clear them first)
74
+ */
75
+ private static function create_cron_jobs() {
76
+ //@todo clear and init schedule
77
+
78
+ }
79
+
80
+ /**
81
+ * Check version
82
+ */
83
+ public static function check_version() {
84
+
85
+ if ( !defined( 'IFRAME_REQUEST' ) ) {
86
+
87
+ if ( get_option( 'dgwt_wcas_version' ) != DGWT_WCAS_VERSION ) {
88
+ self::install();
89
+ }
90
+ }
91
+ }
92
+
93
+ }
94
+
95
+
96
+ DGWT_WCAS_Install::init();
includes/integrations/wp-tao.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Handles integration between WP Tao and Ajax Search for WooCommerce
5
+ *
6
+ * Requires: WP Tao 1.2 or higher
7
+ *
8
+ * @see https://pl.wordpress.org/plugins/wp-tao/
9
+ */
10
+
11
+ class DGWT_WCAS_WP_Tao_integrate {
12
+ /*
13
+ * Constructor
14
+ */
15
+
16
+ function __construct() {
17
+
18
+ // Run only on WP Tao version
19
+ if ( defined( 'WTBP_WPTAO_VERSION' ) && version_compare( WTBP_WPTAO_VERSION, '1.1.9.3', '>' ) ) {
20
+
21
+ add_action( 'wp_footer', array( $this, 'print_track_script' ), 99 );
22
+
23
+ add_filter( 'wptao_event_search_title', array( $this, 'event_search_title' ), 10, 2 );
24
+
25
+ add_filter( 'wptao_event_search_description', array( $this, 'event_search_desc' ), 10, 2 );
26
+ }
27
+ }
28
+
29
+ /*
30
+ * Print tracking sripts
31
+ * @see http://wptao.org/documentation/developers-guide/javascript-events/
32
+ */
33
+
34
+ public function print_track_script() {
35
+ ?>
36
+ <script>
37
+ if ( typeof wptaoEvent == 'function' && window.jQuery ) {
38
+ jQuery( function ( $ ) {
39
+
40
+ $( document ).on( 'click', '.dgwt-wcas-suggestion', function () {
41
+
42
+ var suggestion = $( this ),
43
+ value = suggestion.find( '.dgwt-wcas-st' ).text(),
44
+ tags = [ 'wp', 'Autocomplete search' ],
45
+ meta = { };
46
+
47
+ if ( typeof suggestion.data( 'post-id' ) != 'undefined' ) {
48
+ meta.post_id = suggestion.data( 'post-id' );
49
+ }
50
+ if ( typeof suggestion.data( 'taxonomy' ) != 'undefined' ) {
51
+ meta.taxonomy = suggestion.data( 'taxonomy' );
52
+ }
53
+ if ( typeof suggestion.data( 'term-id' ) != 'undefined' ) {
54
+ meta.term_id = suggestion.data( 'term-id' );
55
+ }
56
+
57
+ wptaoEvent( 'search', value, tags, meta );
58
+
59
+ } );
60
+ } );
61
+ }
62
+ </script>
63
+ <?php
64
+
65
+ }
66
+
67
+ /*
68
+ * Change event title
69
+ */
70
+
71
+ function event_search_title( $title, $event ) {
72
+
73
+ if ( !empty( $event->value ) ) {
74
+
75
+ if ( isset( $event->meta[ 'post_id' ] ) && isset( $event->meta[ 'post_id' ] ) ) {
76
+
77
+ $post = get_post( absint( $event->meta[ 'post_id' ] ) );
78
+
79
+ if ( !empty( $post ) ) {
80
+ $link = get_permalink( $post );
81
+ $phrase = '<a href="' . $link . '">' . esc_attr( $post->post_title ) . '</a>';
82
+ $title = sprintf( __( 'Autosuggestion was clicked: %s', WTBP_WPTAO_DOMAIN ), $phrase );
83
+ }
84
+ }
85
+
86
+ // Clicked category or tag suggestion
87
+ if ( isset( $event->meta[ 'taxonomy' ] ) && isset( $event->meta[ 'term_id' ] ) ) {
88
+
89
+ $term_id = absint( $event->meta[ 'term_id' ] );
90
+ $taxonomny = sanitize_title( $event->meta[ 'taxonomy' ] );
91
+
92
+ $term = get_term_by( 'id', $term_id, $taxonomny );
93
+
94
+ if ( !empty( $term ) ) {
95
+ $link = get_term_link( $term, $taxonomy );
96
+ $phrase = '<a href="' . $link . '">' . esc_attr( $term->name ) . '</a>';
97
+ $title = sprintf( __( 'Autosuggestion was clicked: %s', WTBP_WPTAO_DOMAIN ), $phrase );
98
+ }
99
+ }
100
+ }
101
+
102
+
103
+
104
+ return $title;
105
+ }
106
+
107
+ /*
108
+ * Change event description
109
+ */
110
+
111
+ public function event_search_desc( $description, $event ) {
112
+
113
+ if ( !empty( $event->value ) && (isset($event->meta[ 'post_id' ]) || isset($event->meta[ 'taxonomy' ]))) {
114
+
115
+ $description .= '<span class="wptao-meta-title">' . __( 'Suggestion type:', WTBP_WPTAO_DOMAIN ) . '</span> ';
116
+
117
+ if ( isset( $event->meta[ 'post_id' ] ) && isset( $event->meta[ 'post_id' ] ) ) {
118
+
119
+ $description .= __( 'single product', WTBP_WPTAO_DOMAIN ) . '<br />';
120
+ }
121
+
122
+ // Clicked category or tag suggestion
123
+ if ( isset( $event->meta[ 'taxonomy' ] ) && isset( $event->meta[ 'term_id' ] ) ) {
124
+
125
+ $term_id = absint( $event->meta[ 'term_id' ] );
126
+ $taxonomny = sanitize_title( $event->meta[ 'taxonomy' ] );
127
+
128
+ if ( $event->meta[ 'taxonomy' ] === DGWT_WCAS_WOO_PRODUCT_CATEGORY ) {
129
+ $description .= __( 'product category', WTBP_WPTAO_DOMAIN ) . '<br />';
130
+ } else {
131
+ $description .= __( 'product tag', WTBP_WPTAO_DOMAIN ) . '<br />';
132
+ }
133
+ }
134
+
135
+ //$description .= '<span class="wptao-meta-title">' . __( 'Generated by:', WTBP_WPTAO_DOMAIN ) . '</span> Ajax Search for WooCommerce plugin';
136
+
137
+ }
138
+
139
+
140
+ return $description;
141
+ }
142
+
143
+ }
144
+
145
+ new DGWT_WCAS_WP_Tao_integrate;
includes/register-scripts.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( !defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
+
8
+ class DGWT_WCAS_Scripts {
9
+
10
+ function __construct() {
11
+
12
+ add_action( 'wp_enqueue_scripts', array( $this, 'js_scripts' ) );
13
+
14
+ add_action( 'wp_print_styles', array( $this, 'css_style' ) );
15
+ }
16
+
17
+ /*
18
+ * Register scripts.
19
+ * Uses a WP hook wp_enqueue_scripts
20
+ */
21
+
22
+ public function js_scripts() {
23
+
24
+ if ( !is_admin() ) {
25
+
26
+ //Strings translation
27
+ $t = array(
28
+ 'sale_badge' => _x( 'sale', 'For product badge: on sale', DGWT_WCAS_DOMAIN ),
29
+ 'featured_badge' => _x( 'featured', 'For product badge: featured', DGWT_WCAS_DOMAIN ),
30
+ );
31
+
32
+ // Main JS
33
+ $localize = array(
34
+ 't' => $t,
35
+ 'ajax_search_endpoint' => dgwt_wcas_get_admin_ajax_url( array( 'action', DGWT_WCAS_SEARCH_ACTION ) ),
36
+ 'ajax_details_endpoint' => dgwt_wcas_get_admin_ajax_url(),
37
+ 'action_search' => DGWT_WCAS_SEARCH_ACTION,
38
+ 'action_result_details' => DGWT_WCAS_RESULT_DETAILS_ACTION,
39
+ 'details_box_pos' => DGWT_WCAS()->settings->get_opt( 'details_box_position' ),
40
+ 'min_chars' => 3,
41
+ 'show_details_box' => false,
42
+ 'show_images' => false,
43
+ 'show_price' => false,
44
+ 'show_desc' => false,
45
+ 'show_sale_badge' => false,
46
+ 'show_featured_badge' => false,
47
+ 'is_rtl' => is_rtl() == true ? true : false,
48
+ 'show_preloader' => false,
49
+ 'preloader_url' => '',
50
+ );
51
+
52
+ // Ajax by wc-ajax fontnd endpoint
53
+ if ( DGWT_WCAS_WC_AJAX_ENDPOINT && class_exists( 'WC_AJAX' ) ) {
54
+ $localize[ 'ajax_search_endpoint' ] = WC_AJAX::get_endpoint( DGWT_WCAS_SEARCH_ACTION );
55
+ $localize[ 'ajax_details_endpoint' ] = WC_AJAX::get_endpoint( DGWT_WCAS_RESULT_DETAILS_ACTION );
56
+
57
+ //@todo custom endpoint
58
+ }
59
+
60
+
61
+ $min_chars = DGWT_WCAS()->settings->get_opt( 'min_chars' );
62
+ if ( !empty( $min_chars ) && is_numeric( $min_chars ) ) {
63
+ $localize[ 'min_chars' ] = absint( $min_chars );
64
+ }
65
+
66
+
67
+ // Show/hide details BOX
68
+ if ( DGWT_WCAS()->settings->get_opt( 'show_details_box' ) === 'on' ) {
69
+ $localize[ 'show_details_box' ] = true;
70
+ }
71
+
72
+ // Show/hide images
73
+ if ( DGWT_WCAS()->settings->get_opt( 'show_product_image' ) === 'on' ) {
74
+ $localize[ 'show_images' ] = true;
75
+ }
76
+
77
+ // Show/hide price
78
+ if ( DGWT_WCAS()->settings->get_opt( 'show_product_price' ) === 'on' ) {
79
+ $localize[ 'show_price' ] = true;
80
+ }
81
+
82
+ // Show/hide description
83
+ if ( DGWT_WCAS()->settings->get_opt( 'show_product_desc' ) === 'on' ) {
84
+ $localize[ 'show_desc' ] = true;
85
+ }
86
+
87
+ // Show/hide sale badge
88
+ if ( DGWT_WCAS()->settings->get_opt( 'show_sale_badge' ) === 'on' ) {
89
+ $localize[ 'show_sale_badge' ] = true;
90
+ }
91
+
92
+ // Show/hide featured badge
93
+ if ( DGWT_WCAS()->settings->get_opt( 'show_featured_badge' ) === 'on' ) {
94
+ $localize[ 'show_featured_badge' ] = true;
95
+ }
96
+
97
+ // Set preloader
98
+ if ( DGWT_WCAS()->settings->get_opt( 'show_preloader' ) === 'on' ) {
99
+ $localize[ 'show_preloader' ] = true;
100
+
101
+ $localize[ 'preloader_url' ] = esc_url( DGWT_WCAS()->settings->get_opt( 'preloader_url' ) );
102
+ }
103
+
104
+ if ( DGWT_WCAS_DEBUG === false ) {
105
+ wp_register_script( 'jquery-dgwt-wcas', DGWT_WCAS_URL . 'assets/js/jquery.dgwt-wcas.min.js', array( 'jquery' ), DGWT_WCAS_VERSION, true );
106
+ } else {
107
+ wp_register_script( 'jquery-dgwt-wcas', DGWT_WCAS_URL . 'assets/js/jquery.dgwt-wcas.js', array( 'jquery' ), DGWT_WCAS_VERSION, true );
108
+ }
109
+ wp_localize_script( 'jquery-dgwt-wcas', 'dgwt_wcas', $localize );
110
+ }
111
+ }
112
+
113
+ /*
114
+ * Register and enqueue style
115
+ * Uses a WP hook wp_print_styles
116
+ */
117
+
118
+ public function css_style() {
119
+
120
+ // Main CSS
121
+ wp_register_style( 'dgwt-wcas-style', DGWT_WCAS_URL . 'assets/css/style.css', array(), DGWT_WCAS_VERSION );
122
+
123
+ wp_enqueue_style( 'dgwt-wcas-style' );
124
+ }
125
+
126
+ }
127
+
128
+ $attach_scripts = new DGWT_WCAS_Scripts;
129
+ ?>
includes/shortcode.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Register Woo Ajax Search shortcode
5
+ *
6
+ * @param array $atts bool show_details_box
7
+ */
8
+ function dgwt_wcas_ajax_search_form_shortcode($atts) {
9
+
10
+ $search_args = shortcode_atts( array(
11
+ 'class' => '',
12
+ 'bar' => 'something else',
13
+ 'details_box' => 'show'
14
+ ), $atts );
15
+
16
+ $search_args[ 'class' ] .= empty( $search_args[ 'class' ] ) ? 'woocommerce' : ' woocommerce';
17
+
18
+ $search_args = apply_filters( 'dgwt_wcas_ajax_search_shortcode_args', $search_args );
19
+
20
+ return dgwt_wcas_get_search_form( $search_args );
21
+ }
22
+
23
+ add_shortcode( 'wcas-search-form', 'dgwt_wcas_ajax_search_form_shortcode' );
includes/style.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ add_action( 'wp_head', 'dgwt_wcas_print_style' );
3
+
4
+ function dgwt_wcas_print_style() {
5
+
6
+ // Search form
7
+ $bg_search_input = DGWT_WCAS()->settings->get_opt( 'bg_input_color' );
8
+ $text_input_color = DGWT_WCAS()->settings->get_opt( 'text_input_color' );
9
+ $border_input_color = DGWT_WCAS()->settings->get_opt( 'border_input_color' );
10
+ $bg_submit_color = DGWT_WCAS()->settings->get_opt( 'bg_submit_color' );
11
+ $text_submit_color = DGWT_WCAS()->settings->get_opt( 'text_submit_color' );
12
+
13
+ // Suggestions
14
+ $sug_hover_color = DGWT_WCAS()->settings->get_opt( 'sug_hover_color' );
15
+ $sug_highlight_color = DGWT_WCAS()->settings->get_opt( 'sug_highlight_color' );
16
+ $sug_text_color = DGWT_WCAS()->settings->get_opt( 'sug_text_color' );
17
+ $sug_bg_color = DGWT_WCAS()->settings->get_opt( 'sug_bg_color' );
18
+ $sug_border_color = DGWT_WCAS()->settings->get_opt( 'sug_border_color' );
19
+ ?>
20
+ <style>
21
+ <?php if ( !empty( $bg_search_input ) || !empty( $text_input_color ) || !empty( $border_input_color ) ): ?>
22
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input,
23
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input:hover,
24
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input:focus{
25
+ <?php echo!empty( $bg_search_input ) ? 'background-color:' . sanitize_text_field( $bg_search_input ) . ';' : ''; ?>
26
+ <?php echo!empty( $text_input_color ) ? 'color:' . sanitize_text_field( $text_input_color ) . ';' : ''; ?>
27
+ <?php echo!empty( $border_input_color ) ? 'border-color:' . sanitize_text_field( $border_input_color ) . ';' : ''; ?>
28
+ }
29
+
30
+
31
+ <?php if ( !empty( $text_input_color ) ): ?>
32
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input::-webkit-input-placeholder {
33
+ color: <?php echo sanitize_text_field( $text_input_color ); ?>;
34
+ opacity:0.3;
35
+ }
36
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input:-moz-placeholder{
37
+ color: <?php echo sanitize_text_field( $text_input_color ); ?>;
38
+ opacity:0.3;
39
+ }
40
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input::-moz-placeholder{
41
+ color: <?php echo sanitize_text_field( $text_input_color ); ?>;
42
+ opacity:0.3;
43
+ }
44
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-input:-ms-input-placeholder {
45
+ color: <?php echo sanitize_text_field( $text_input_color ); ?>;
46
+ opacity:0.3;
47
+ }
48
+ .dgwt-wcas-no-submit.dgwt-wcas-search-wrapp .dgwt-wcas-ico-loupe {
49
+ fill: <?php echo sanitize_text_field( $text_input_color ); ?>;
50
+ }
51
+ <?php endif; ?>
52
+ <?php endif; ?>
53
+
54
+
55
+
56
+ <?php
57
+ // Submit button
58
+ if ( !empty( $bg_submit_color ) || !empty( $text_submit_color ) ):
59
+ ?>
60
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit::before {
61
+ <?php echo!empty( $bg_submit_color ) ? 'border-color: transparent ' . sanitize_text_field( $bg_submit_color ) . ';' : ''; ?>
62
+ }
63
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:hover::before,
64
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:focus::before {
65
+ <?php echo!empty( $bg_submit_color ) ? 'border-right-color: ' . sanitize_text_field( $bg_submit_color ) . ';' : ''; ?>
66
+ }
67
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit {
68
+ <?php echo!empty( $bg_submit_color ) ? 'background-color: ' . sanitize_text_field( $bg_submit_color ) . ';' : ''; ?>
69
+ <?php echo!empty( $text_submit_color ) ? 'color: ' . sanitize_text_field( $text_submit_color ) . ';' : ''; ?>
70
+ }
71
+
72
+ .dgwt-wcas-search-wrapp .dgwt-wcas-ico-loupe{
73
+ <?php echo!empty( $text_submit_color ) ? 'fill: ' . sanitize_text_field( $text_submit_color ) . ';' : ''; ?>
74
+ }
75
+ <?php endif; ?>
76
+
77
+ <?php
78
+ // Submit button
79
+ if ( !empty( $bg_submit_color ) || !empty( $text_submit_color ) ):
80
+ ?>
81
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit::before {
82
+ <?php echo!empty( $bg_submit_color ) ? 'border-color: transparent ' . sanitize_text_field( $bg_submit_color ) . ';' : ''; ?>
83
+ }
84
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:hover::before,
85
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit:focus::before {
86
+ <?php echo!empty( $bg_submit_color ) ? 'border-right-color: ' . sanitize_text_field( $bg_submit_color ) . ';' : ''; ?>
87
+ }
88
+ .dgwt-wcas-search-wrapp .dgwt-wcas-sf-wrapp .dgwt-wcas-search-submit {
89
+ <?php echo!empty( $bg_submit_color ) ? 'background-color: ' . sanitize_text_field( $bg_submit_color ) . ';' : ''; ?>
90
+ <?php echo!empty( $text_submit_color ) ? 'color: ' . sanitize_text_field( $text_submit_color ) . ';' : ''; ?>
91
+ }
92
+
93
+ .dgwt-wcas-search-wrapp .dgwt-wcas-ico-loupe{
94
+ <?php echo!empty( $text_submit_color ) ? 'fill: ' . sanitize_text_field( $text_submit_color ) . ';' : ''; ?>
95
+ }
96
+ <?php endif; ?>
97
+
98
+ <?php if ( !empty( $sug_bg_color ) ): ?>
99
+ .dgwt-wcas-search-wrapp .dgwt-wcas-suggestions-wrapp{
100
+ <?php echo!empty( $sug_bg_color ) ? 'background-color: ' . sanitize_text_field( $sug_bg_color ) . ';' : ''; ?>
101
+ }
102
+ <?php endif; ?>
103
+
104
+ <?php if ( !empty( $sug_hover_color ) ): ?>
105
+ .dgwt-wcas-search-wrapp .dgwt-wcas-suggestion-selected{
106
+ <?php echo!empty( $sug_hover_color ) ? 'background-color: ' . sanitize_text_field( $sug_hover_color ) . ';' : ''; ?>
107
+ }
108
+ <?php endif; ?>
109
+
110
+ <?php if ( !empty( $sug_text_color ) ): ?>
111
+ .dgwt-wcas-suggestion *
112
+ {
113
+ <?php echo!empty( $sug_text_color ) ? 'color: ' . sanitize_text_field( $sug_text_color ) . ';' : ''; ?>
114
+ }
115
+ <?php endif; ?>
116
+
117
+ <?php if ( !empty( $sug_highlight_color ) ): ?>
118
+ .dgwt-wcas-search-wrapp .dgwt-wcas-st strong{
119
+ <?php echo!empty( $sug_highlight_color ) ? 'color: ' . sanitize_text_field( $sug_highlight_color ) . ';' : ''; ?>
120
+ }
121
+ <?php endif; ?>
122
+
123
+ <?php if ( !empty( $sug_border_color ) ): ?>
124
+ .dgwt-wcas-search-wrapp .dgwt-wcas-suggestions-wrapp,
125
+ .dgwt-wcas-details-wrapp,
126
+ .dgwt-wcas-suggestion{
127
+ <?php echo!empty( $sug_border_color ) ? 'border-color: ' . sanitize_text_field( $sug_border_color ) . ';' : ''; ?>
128
+ }
129
+ <?php endif; ?>
130
+
131
+ </style>
132
+
133
+
134
+ <?php
135
+ }
includes/tmpl/search-form.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( !defined( 'DGWT_WCAS_FILE' ) ) {
4
+ exit;
5
+ }
6
+
7
+ $submit_text = DGWT_WCAS()->settings->get_opt( 'search_submit_text' );
8
+ $has_submit = DGWT_WCAS()->settings->get_opt( 'show_submit_button' );
9
+ ?>
10
+
11
+ <div class="dgwt-wcas-search-wrapp <?php echo dgwt_wcas_search_css_classes( $args ); ?>">
12
+ <form class="dgwt-wcas-search-form" role="search" action="<?php echo esc_url( home_url( '/' ) ) ?>" method="get">
13
+ <div class="dgwt-wcas-sf-wrapp">
14
+ <?php
15
+ if($has_submit !== 'on'){
16
+ dgwt_wcas_print_ico_loupe();
17
+ }
18
+ ?>
19
+ <label class="screen-reader-text" for="dgwt-wcas-search"><?php _e( 'Products search', DGWT_WCAS_DOMAIN ) ?></label>
20
+
21
+ <input
22
+ type="search"
23
+ id="dgwt-wcas-search"
24
+ class="dgwt-wcas-search-input"
25
+ name="s"
26
+ value="<?php echo get_search_query() ?>"
27
+ placeholder="<?php echo DGWT_WCAS()->settings->get_opt( 'search_placeholder', __( 'Search for products...', DGWT_WCAS_DOMAIN ) ) ?>"
28
+ />
29
+ <div class="dgwt-wcas-preloader"></div>
30
+
31
+ <?php if($has_submit === 'on'): ?>
32
+ <button type="submit" class="dgwt-wcas-search-submit"><?php echo empty( $submit_text ) ? dgwt_wcas_print_ico_loupe() : esc_html( $submit_text ); ?></button>
33
+ <?php endif; ?>
34
+
35
+ <input type="hidden" name="post_type" value="product" />
36
+
37
+
38
+ <?php
39
+ // WPML compatible
40
+ if ( defined( 'ICL_LANGUAGE_CODE' ) ):
41
+ ?>
42
+ <input type="hidden" name="lang" value="<?php echo( ICL_LANGUAGE_CODE ); ?>" />
43
+ <?php endif ?>
44
+
45
+ </div>
46
+ </form>
47
+ </div>
includes/tmpl/single-product-tax.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $rew_count = $product->get_review_count();
3
+ ?>
4
+
5
+ <a class="dgwt-wcas-tax-product-details" href="<?php echo esc_url( get_permalink( $product->id ) ); ?>" title="<?php echo esc_attr( $product->get_title() ); ?>">
6
+
7
+ <div class="dgwt-wcas-tpd-image">
8
+ <?php echo $product->get_image( array( 60, 60 ) ); ?>
9
+ </div>
10
+
11
+ <div class="dgwt-wcas-tpd-rest">
12
+
13
+ <span class="product-title"><?php echo $product->get_title(); ?></span>
14
+
15
+ <?php if ( $rew_count > 0 ): ?>
16
+
17
+ <div class="dgwt-wcas-pd-rating">
18
+ <?php echo $product->get_rating_html() . ' <span class="dgwt-wcas-pd-review">(' . $rew_count . ')</span>'; ?>
19
+ </div>
20
+
21
+ <?php endif; ?>
22
+
23
+ <div class="dgwt-wcas-pd-price">
24
+ <?php echo $product->get_price_html(); ?>
25
+ </div>
26
+
27
+ <?php if ( !empty( $details[ 'desc' ] ) ): ?>
28
+ <div class="dgwt-wcas-pd-desc">
29
+ <?php echo wp_kses_post( $details[ 'desc' ] ); ?>
30
+ </div>
31
+ <?php endif; ?>
32
+ </div>
33
+
34
+ </a>
includes/tmpl/single-product.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $rew_count = $product->get_review_count();
3
+ ?>
4
+ <div class="dgwt-wcas-details-inner">
5
+ <div class="dgwt-wcas-product-details">
6
+
7
+ <a class="dgwt-wcas-pd-details" href="<?php echo esc_url( get_permalink( $product->id ) ); ?>" title="<?php echo esc_attr( $product->get_title() ); ?>">
8
+
9
+ <div class="dgwt-wcas-pd-image">
10
+ <?php echo $product->get_image( array( 60, 60 ) ); ?>
11
+ </div>
12
+
13
+ <div class="dgwt-wcas-pd-rest">
14
+
15
+ <span class="product-title"><?php echo $product->get_title(); ?></span>
16
+
17
+ <?php if ( $rew_count > 0 ): ?>
18
+
19
+ <div class="dgwt-wcas-pd-rating">
20
+ <?php echo $product->get_rating_html() . ' <span class="dgwt-wcas-pd-review">(' . $rew_count . ')</span>'; ?>
21
+ </div>
22
+
23
+ <?php endif; ?>
24
+
25
+ <div class="dgwt-wcas-pd-price">
26
+ <?php echo $product->get_price_html(); ?>
27
+ </div>
28
+ </div>
29
+
30
+ </a>
31
+
32
+ <?php if ( !empty( $details[ 'desc' ] ) ): ?>
33
+ <div class="dgwt-wcas-pd-desc">
34
+ <?php echo wp_kses_post( $details[ 'desc' ] ); ?>
35
+ </div>
36
+ <?php endif; ?>
37
+
38
+ <div class="dgwt-wcas-pd-addtc">
39
+ <?php
40
+ echo WC_Shortcodes::product_add_to_cart( array(
41
+ 'id' => $product->id,
42
+ 'show_price' => false,
43
+ 'style' => '',
44
+ ) );
45
+ ?>
46
+ </div>
47
+
48
+
49
+ </div>
50
+ </div>
includes/widget.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( class_exists( 'WC_Widget' ) ) {
4
+
5
+
6
+ add_action( 'widgets_init', function() {
7
+ register_widget( 'DGWT_WCAS_Search_Widget' );
8
+ } );
9
+
10
+ class DGWT_WCAS_Search_Widget extends WC_Widget {
11
+
12
+ /**
13
+ * Constructor
14
+ */
15
+ public function __construct() {
16
+
17
+
18
+ $this->widget_cssclass = 'woocommerce widget_search dgwt_wcas_ajax_search';
19
+ $this->widget_description = __( 'Ajax (live) search form for WooCommerce', DGWT_WCAS_DOMAIN );
20
+ $this->widget_id = 'dgwt_wcas_ajax_search';
21
+ $this->widget_name = __( 'Woo Ajax Search', DGWT_WCAS_DOMAIN );
22
+ $this->settings = array(
23
+ 'title' => array(
24
+ 'type' => 'text',
25
+ 'std' => '',
26
+ 'label' => __( 'Title', DGWT_WCAS_DOMAIN )
27
+ )
28
+ );
29
+
30
+
31
+ parent::__construct();
32
+ }
33
+
34
+ /**
35
+ * Outputs the content of the widget
36
+ *
37
+ * @param array $args
38
+ * @param array $instance
39
+ */
40
+ public function widget( $args, $instance ) {
41
+
42
+ $this->widget_start( $args, $instance );
43
+
44
+ echo dgwt_wcas_get_search_form();
45
+
46
+ $this->widget_end( $args );
47
+ }
48
+
49
+ }
50
+
51
+ }
readme.txt ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Ajax Search for WooCommerce ===
2
+ Contributors: damian-gora
3
+ Tags: AJAX, ajax search, autocomplete, category search, custom search, ecommerce, instant search, sive search, product search, products, search, search by sku, search highlight, search plugin, shop, woocommerce, woocommerce live search, WooCommerce Plugin, woocommerce product search, woocommerce search, wordpress search, wp ajax search, wp search, wp search plugin, wp tao
4
+ Requires at least: 3.8
5
+ Tested up to: 4.5.2
6
+ Stable tag: 0.9
7
+ License: GPLv2 or later
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+
10
+ Help users easily find and discover products in your store using Ajax Search for WooCommerce – a highly customizable live search plugin.
11
+
12
+ == Description ==
13
+
14
+ The plugin allows you to display the WooCommerce AJAX search form anywhere on the page.
15
+
16
+ Just enter a few letters and the products which best match your query will appear.
17
+ Suggestions can be displayed in a simple form (names of the products only) or in an extended form (includes photos, prices, descriptions, extended information etc.).
18
+
19
+ Ajax Search for WooCommerce has been designed to enhance user search experience to the maximum.
20
+
21
+ = Free =
22
+ This plugin is completely free of charge and provides the whole range of functions which are included in some paid plugins.
23
+ Initially, I created the plugin for my personal use, but I have decided to include new features and make it available to WordPress community.
24
+
25
+ = Demo =
26
+ See how it works on the [DEMO](http://damiangora.com/ajax-search-for-woocommerce) site.
27
+
28
+
29
+ = Features =
30
+ * Search in **products titles, descriptions, excerpt, categories, tags or SKU**.
31
+ * **Product image** displayed for each suggestion
32
+ * **Price** displayed for each suggestion
33
+ * **Description** displayed for each suggestion
34
+ * The **'add to cart' button and** and **extended information** displayed when you hover the mouse over the suggestion
35
+ * **Categories and tags** as suggestions
36
+ * **Limit** displayed suggestions – you can set your own
37
+ * **The minimum number of characters** required to display suggestions – you can set your own
38
+ * You can set your own **label on the 'search' button**
39
+ * You can set your own **preloader image**
40
+ * You can set your own **colour scheme** for the 10 main form elements and hints
41
+ * **[WP Tao](https://wordpress.org/plugins/wp-tao) integration** - allows you to track and analyze search results of a website users. Each click on the suggestion is logged. Read more on [wptao.org](http://wptao.org/documentation/user-guide/).
42
+
43
+ = How to use? =
44
+ 1. Use shorcode [wcas-search-form] in page/post editor or <?php echo do_shortcode('[wcas-search-form]'); ?> in your Child Theme template files.
45
+ 2. Go to the "Widgets Screen" and assign widget "Woo Ajax Search" to one of the widget area.
46
+
47
+ = Feedback =
48
+
49
+ Any suggestions or comments are welcome. Feel free to contact me using this [contact form](http://damiangora.com/ajax-search-for-woocommerce/contact).
50
+
51
+ == Installation ==
52
+
53
+ 1. Install the plugin from within the Dashboard or upload the directory `ajax-search-for-woocommerce` and all its contents to the `/wp-content/plugins/` directory.
54
+ 2. Activate the plugin through the 'Plugins' menu in WordPress.
55
+ 3. Go to Woo Ajax Search (admin menu) and set your preferences.
56
+ 4. Use shorcode [wcas-search-form] or go to the Widgets Screen and choose "Woo Ajax Search"
57
+
58
+ == Screenshots ==
59
+
60
+ 1. Basic suggestions
61
+ 2. Extra elements
62
+ 3. Extended suggestions
63
+
64
+ == Changelog ==
65
+
66
+ = 0.9, May 17, 2016 =
67
+ * First public release
uninstall.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Uninstall the plugin
4
+ */
5
+ // Exit if accessed directly
6
+ if ( !defined( 'WP_UNINSTALL_PLUGIN' ) )
7
+ exit;
8
+
9
+ //@todo deregister schedule