Issues (823)

classes/class-frontend.php (4 issues)

1
<?php
2
/**
3
 * LSX Search Frontend Class.
4
 *
5
 * @package lsx-search
6
 */
7
8
namespace lsx\search\classes;
9
10
class Frontend {
11
12
	/**
13
	 * Holds class instance
14
	 *
15
	 * @since 1.0.0
16
	 *
17
	 * @var      object \lsx\search\classes\Frontend()
18
	 */
19
	protected static $instance = null;
20
21
	public $options = false;
22
23
	public $tabs = false;
24
25
	public $facet_data = false;
26
27
	/**
28
	 * Determine weather or not search is enabled for this page.
29
	 *
30
	 * @var boolean
31
	 */
32
	public $search_enabled = false;
33
34
	public $search_core_suffix = false;
35
36
	public $search_prefix = false;
37
38
	/**
39
	 * Holds the post types enabled
40
	 *
41
	 * @var array
42
	 */
43
	public $post_types = array();
44
45
	/**
46
	 * Holds the taxonomies enabled for search
47
	 *
48
	 * @var array
49
	 */
50
	public $taxonomies = array();
51
52
	/**
53
	 * If the current search page has posts or not
54
	 *
55
	 * @var boolean
56
	 */
57
	public $has_posts = false;
58
59
	/**
60
	 * If we are using the CMB2 options or not.
61
	 *
62
	 * @var boolean
63
	 */
64
	public $new_options = false;
65
66
	/**
67
	 * Construct method.
68
	 */
69
	public function __construct() {
70
		$this->options = \lsx\search\includes\get_options();
71
		$this->load_classes();
72
73
		add_filter( 'wpseo_json_ld_search_url', array( $this, 'change_json_ld_search_url' ), 10, 1 );
74
		add_action( 'wp', array( $this, 'set_vars' ), 21 );
75
		add_action( 'wp', array( $this, 'set_facetwp_vars' ), 22 );
76
		add_action( 'wp', array( $this, 'core' ), 23 );
77
		add_action( 'lsx_body_top', array( $this, 'check_for_results' ) );
78
79
		add_filter( 'pre_get_posts', array( $this, 'ignore_sticky_search' ) );
80
		add_action( 'pre_get_posts', array( $this, 'filter_post_types' ) );
81
82
		add_filter( 'lsx_search_post_types', array( $this, 'register_post_types' ) );
83
		add_filter( 'lsx_search_taxonomies', array( $this, 'register_taxonomies' ) );
84
		add_filter( 'lsx_search_post_types_plural', array( $this, 'register_post_type_tabs' ) );
85
		add_filter( 'facetwp_sort_options', array( $this, 'facetwp_sort_options' ), 10, 2 );
86
		add_filter( 'wp_kses_allowed_html', array( $this, 'kses_allowed_html' ), 20, 2 );
87
		add_filter( 'get_search_query', array( $this, 'get_search_query' ) );
88
89
		// Redirects.
90
		add_action( 'template_redirect', array( $this, 'pretty_search_redirect' ) );
91
		add_filter( 'pre_get_posts', array( $this, 'pretty_search_parse_query' ) );
92
93
		add_action( 'lsx_search_sidebar_top', array( $this, 'search_sidebar_top' ) );
94
		add_filter( 'facetwp_facet_html', array( $this, 'search_facet_html' ), 10, 2 );
95
	}
96
97
	/**
98
	 * Return an instance of this class.
99
	 *
100
	 * @since 1.0.0
101
	 *
102
	 * @return    object \lsx\member_directory\search\Frontend()    A single instance of this class.
103
	 */
104
	public static function get_instance() {
105
		// If the single instance hasn't been set, set it now.
106
		if ( null === self::$instance ) {
107
			self::$instance = new self();
108
		}
109
		return self::$instance;
110
	}
111
112
	/**
113
	 * Loads the variable classes and the static classes.
114
	 */
115
	private function load_classes() {
116
		require_once LSX_SEARCH_PATH . 'classes/frontend/class-layout.php';
117
		$this->layout = frontend\Layout::get_instance();
118
	}
119
120
	/**
121
	 * Check all settings.
122
	 */
123
	public function set_vars() {
124
		$post_type = '';
125
126
		$this->post_types      = apply_filters( 'lsx_search_post_types', array() );
127
		$this->taxonomies      = apply_filters( 'lsx_search_taxonomies', array() );
128
		$this->tabs            = apply_filters( 'lsx_search_post_types_plural', array() );
129
		$this->options         = apply_filters( 'lsx_search_options', $this->options );
130
		$this->post_types      = get_post_types();
131
		$this->post_type_slugs = array(
132
			'post'        => 'posts',
133
			'project'     => 'projects',
134
			'service'     => 'services',
135
			'team'        => 'team',
136
			'testimonial' => 'testimonials',
137
			'video'       => 'videos',
138
			'product'     => 'products',
139
		);
140
		$this->set_search_prefix();
141
		$this->get_cmb2_options();
142
		$this->search_enabled = apply_filters( 'lsx_search_enabled', $this->is_search_enabled(), $this );
143
		$this->search_prefix  = apply_filters( 'lsx_search_prefix', $this->search_prefix, $this );
144
	}
145
146
	private function get_cmb2_options() {
147
		$cmb2_options = get_option( 'lsx-search-settings' );
148
		if ( false !== $cmb2_options && ! empty( $cmb2_options ) ) {
149
			$this->set_search_prefix( true );
150
			$this->options['display'] = $cmb2_options;
151
			foreach ( $this->options['display'] as $option_key => $option_value ) {
152
				if ( is_array( $option_value ) && ! empty( $option_value ) ) {
153
					$new_values = array();
154
					foreach ( $option_value as $empty_key => $key_value ) {
155
						$new_values[ $key_value ] = 'on';
156
					}
157
					$this->options['display'][ $option_key ] = $new_values;
158
				}
159
			}
160
			$this->new_options = true;
161
			$this->disable_to_search_actions();
162
		}
163
	}
164
165
	private function disable_to_search_actions() {
166
		global $lsx_to_search_fwp, $lsx_to_search;
167
		if ( null !== $lsx_to_search ) {
168
			// Redirects.
169
			remove_filter( 'template_include', array( $lsx_to_search, 'search_template_include' ), 99 );
170
			remove_action( 'template_redirect', array( $lsx_to_search, 'pretty_search_redirect' ) );
171
			remove_filter( 'pre_get_posts', array( $lsx_to_search, 'pretty_search_parse_query' ) );
172
173
			// Layout Filter.
174
			remove_filter( 'lsx_layout', array( $lsx_to_search, 'lsx_layout' ), 20, 1 );
175
			remove_filter( 'lsx_layout_selector', array( $lsx_to_search, 'lsx_layout_selector' ), 10, 4 );
176
			remove_filter( 'lsx_to_archive_layout', array( $lsx_to_search, 'lsx_to_search_archive_layout' ), 10, 2 );
177
178
			remove_action( 'lsx_search_sidebar_top', array( $lsx_to_search, 'search_sidebar_top' ) );
179
			remove_action( 'pre_get_posts', array( $lsx_to_search, 'price_sorting' ), 100 );
180
181
			//add_shortcode( 'lsx_search_form', array( 'LSX_TO_Search_Frontend', 'search_form' ) );
182
			remove_filter( 'searchwp_short_circuit', array( $lsx_to_search, 'searchwp_short_circuit' ), 10, 2 );
183
			remove_filter( 'get_search_query', array( $lsx_to_search, 'get_search_query' ) );
184
			remove_filter( 'body_class', array( $lsx_to_search, 'to_add_search_url_class' ), 20 );
185
186
			remove_filter( 'facetwp_preload_url_vars', array( $lsx_to_search, 'preload_url_vars' ), 10, 1 );
187
			remove_filter( 'wpseo_json_ld_search_url', array( $lsx_to_search, 'change_json_ld_search_url' ), 10, 1 );
188
		}
189
		if ( null !== $lsx_to_search_fwp ) {
190
			remove_filter( 'facetwp_indexer_row_data', array( $lsx_to_search_fwp, 'facetwp_index_row_data' ), 10, 2 );
191
			remove_filter( 'facetwp_index_row', array( $lsx_to_search_fwp, 'facetwp_index_row' ), 10, 2 );
192
193
			remove_filter( 'facetwp_sort_options', array( $lsx_to_search_fwp, 'facet_sort_options' ), 10, 2 );
194
195
			remove_filter( 'facetwp_pager_html', array( $lsx_to_search_fwp, 'facetwp_pager_html' ), 10, 2 );
196
			remove_filter( 'facetwp_result_count', array( $lsx_to_search_fwp, 'facetwp_result_count' ), 10, 2 );
197
198
			remove_filter( 'facetwp_facet_html', array( $lsx_to_search_fwp, 'destination_facet_html' ), 10, 2 );
199
			remove_filter( 'facetwp_facet_html', array( $lsx_to_search_fwp, 'slide_facet_html' ), 10, 2 );
200
			remove_filter( 'facetwp_facet_html', array( $lsx_to_search_fwp, 'search_facet_html' ), 10, 2 );
201
			remove_filter( 'facetwp_load_css', array( $lsx_to_search_fwp, 'facetwp_load_css' ), 10, 1 );
202
203
			if ( class_exists( 'LSX_Currencies' ) ) {
204
				remove_filter( 'facetwp_render_output', array( $lsx_to_search_fwp, 'slide_price_lsx_currencies' ), 10, 2 );
205
			} else {
206
				remove_filter( 'facetwp_render_output', array( $lsx_to_search_fwp, 'slide_price_to_currencies' ), 10, 2 );
207
			}
208
		}
209
	}
210
211
	/**
212
	 * Returns if the search is enabled.
213
	 *
214
	 * @return boolean
215
	 */
216
	public function is_search_enabled() {
217
		$search_enabled = false;
218
219
		if ( false === $this->new_options ) {
220
			if ( isset( $this->options['display'][ $this->search_prefix . '_enable_' . $this->search_core_suffix ] ) && ( ! empty( $this->options ) ) && 'on' == $this->options['display'][ $this->search_prefix . '_enable_' . $this->search_core_suffix ] ) {
221
				$search_enabled = true;
222
			}
223
		} else {
224
			$enable_prefix = $this->search_prefix;
225
			if ( ! empty( $this->options ) && isset( $this->options['display'] ) && isset( $this->options['display'][ $enable_prefix . '_enable' ] ) && 'on' === $this->options['display'][ $enable_prefix . '_enable' ] ) {
226
				$search_enabled = true;
227
			}
228
		}
229
230
		// These are specific plugin exclusions.
231
		if ( is_tax( array( 'wcpv_product_vendors' ) ) ) {
232
			$search_enabled = false;
233
		}
234
		return $search_enabled;
235
	}
236
237
	/**
238
	 * Sets the search prefix.
239
	 *
240
	 * @return void
241
	 */
242
	private function set_search_prefix( $new_prefixes = false ) {
243
		$page_for_posts = get_option( 'page_for_posts' );
244
		if ( false !== $new_prefixes ) {
245
			$this->taxonomies = array();
246
			$this->post_types = array();
247
		}
248
249
		if ( is_search() ) {
250
			if ( false === $new_prefixes ) {
251
				$this->search_core_suffix = 'core';
252
				$this->search_prefix      = 'search';
253
			} else {
254
				$this->search_core_suffix = 'enable';
255
				$this->search_prefix      = 'engine_search';
256
			}
257
		} elseif ( is_post_type_archive( $this->post_types ) || is_tax() || is_page( $page_for_posts ) || is_home() || is_category() || is_tag() ) {
258
			if ( false === $new_prefixes ) {
259
				$this->search_core_suffix = 'search';
260
			} else {
261
				$this->search_core_suffix = 'enable';
262
			}
263
264
			if ( is_tax() ) {
265
				$tax = get_query_var( 'taxonomy' );
266
				$tax = get_taxonomy( $tax );
267
				$post_type = $tax->object_type[0];
268
			} else if ( is_page( $page_for_posts ) || is_category() || is_tag() || is_home() ) {
269
				$post_type = 'post';
270
			} else {
271
				$post_type = get_query_var( 'post_type' );
272
			}
273
274
			if ( false === $new_prefixes ) {
275
				if ( isset( $this->tabs[ $post_type ] ) ) {
276
					$this->search_prefix = $this->tabs[ $post_type ] . '_archive';
277
				}
278
			} else {
279
				$this->search_prefix = $post_type . '_search';
280
			}
281
		}
282
	}
283
284
	/**
285
	 * Sets the FacetWP variables.
286
	 */
287
	public function set_facetwp_vars() {
288
289
		if ( class_exists( 'FacetWP' ) ) {
290
			$facet_data = FWP()->helper->get_facets();
291
		}
292
293
		$this->facet_data = array();
294
295
		$this->facet_data['search_form'] = array(
296
			'name' => 'search_form',
297
			'label' => esc_html__( 'Search Form', 'lsx-search' ),
298
		);
299
300
		if ( ! empty( $facet_data ) && is_array( $facet_data ) ) {
301
			foreach ( $facet_data as $facet ) {
302
				$this->facet_data[ $facet['name'] ] = $facet;
303
			}
304
		}
305
	}
306
307
	/**
308
	 * Check all settings.
309
	 */
310
	public function core() {
311
312
		if ( true === $this->search_enabled ) {
313
			add_action( 'wp_enqueue_scripts', array( $this, 'assets' ), 999 );
314
315
			add_filter( 'lsx_layout', array( $this, 'lsx_layout' ), 20, 1 );
316
			add_filter( 'lsx_layout_selector', array( $this, 'lsx_layout_selector' ), 10, 4 );
317
			add_filter( 'lsx_slot_class', array( $this, 'change_slot_column_class' ) );
318
			add_action( 'lsx_entry_top', array( $this, 'add_label_to_title' ) );
319
			add_filter( 'body_class', array( $this, 'body_class' ), 10 );
320
321
			add_filter( 'lsx_blog_customizer_top_of_blog_action', array( $this, 'top_of_blog_action' ), 10, 1 );
322
			add_filter( 'lsx_blog_customizer_blog_description_class', array( $this, 'blog_description_class' ), 10, 1 );
323
324
			if ( class_exists( 'LSX_Videos' ) ) {
325
				global $lsx_videos_frontend;
326
				remove_action( 'lsx_content_top', array( $lsx_videos_frontend, 'categories_tabs' ), 15 );
327
			}
328
329
			add_filter( 'lsx_paging_nav_disable', '__return_true' );
330
			add_action( 'lsx_content_top', array( $this, 'facet_top_bar' ) );
331
			add_action( 'lsx_content_top', array( $this, 'facetwp_tempate_open' ) );
332
			add_action( 'lsx_content_bottom', array( $this, 'facetwp_tempate_close' ) );
333
			add_action( 'lsx_content_bottom', array( $this, 'facet_bottom_bar' ) );
334
335
			if ( ! empty( $this->options['display'][ $this->search_prefix . '_layout' ] ) && '1c' !== $this->options['display'][ $this->search_prefix . '_layout' ] ) {
336
				add_filter( 'lsx_sidebar_enable', array( $this, 'lsx_sidebar_enable' ), 10, 1 );
337
			}
338
339
			add_action( 'lsx_content_wrap_before', array( $this, 'search_sidebar' ), 150 );
340
341
			if ( class_exists( 'WooCommerce' ) && ( is_shop() || is_product_category() || is_product_tag() ) ) {
342
				remove_action( 'woocommerce_archive_description', 'woocommerce_taxonomy_archive_description' );
343
				remove_action( 'woocommerce_archive_description', 'woocommerce_product_archive_description' );
344
				add_filter( 'woocommerce_show_page_title', '__return_false' );
345
346
				add_filter( 'loop_shop_columns', function() {
347
					return 3;
348
				} );
349
350
				// Actions added by LSX theme
351
				remove_action( 'lsx_content_wrap_before', 'lsx_global_header' );
352
353
				// Actions added be LSX theme / woocommerce.php file
354
				remove_action( 'woocommerce_after_shop_loop', 'lsx_wc_sorting_wrapper', 9 );
355
				remove_action( 'woocommerce_after_shop_loop', 'woocommerce_catalog_ordering', 10 );
356
				remove_action( 'woocommerce_after_shop_loop', 'woocommerce_result_count', 20 );
357
				remove_action( 'woocommerce_after_shop_loop', 'woocommerce_pagination', 30 );
358
				remove_action( 'woocommerce_after_shop_loop', 'lsx_wc_sorting_wrapper_close', 31 );
359
360
				// Actions added be LSX theme / woocommerce.php file
361
				remove_action( 'woocommerce_before_shop_loop', 'lsx_wc_sorting_wrapper', 9 );
362
				remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 10 );
363
				remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 );
364
				remove_action( 'woocommerce_before_shop_loop', 'lsx_wc_woocommerce_pagination', 30 );
365
				remove_action( 'woocommerce_before_shop_loop', 'lsx_wc_sorting_wrapper_close', 31 );
366
			}
367
		}
368
	}
369
370
	/**
371
	 * Adds a search class to the body to allow the styling of the sidebars etc.
372
	 *
373
	 * @param  array $classes The classes.
374
	 * @return array $classes The classes.
375
	 */
376
	public function body_class( $classes ) {
377
		$classes[] = 'lsx-search-enabled';
378
		return $classes;
379
	}
380
381
	/**
382
	 * Moves the blog description to above the content columns.
383
	 *
384
	 * @param  string $action
385
	 * @return string $action
386
	 */
387
	public function top_of_blog_action( $action = '' ) {
388
		$action = 'lsx_content_wrap_before';
389
		return $action;
390
	}
391
392
	/**
393
	 * Adds a class to the blog description.
394
	 *
395
	 * @param  string $action
396
	 * @return string $action
397
	 */
398
	public function blog_description_class( $class = '' ) {
399
		$class .= ' col-md-12 search-description';
400
		return $class;
401
	}
402
403
	/**
404
	 * Check the $wp_query global to see if there are posts in the current query.
405
	 *
406
	 * @return void
407
	 */
408
	public function check_for_results() {
409
		if ( true === $this->search_enabled ) {
410
			global $wp_query;
411
			if ( empty( $wp_query->posts ) ) {
412
				$this->has_posts = false;
413
				remove_action( 'lsx_content_top', array( $this, 'facet_top_bar' ) );
414
				remove_action( 'lsx_content_bottom', array( $this, 'facet_bottom_bar' ) );
415
				remove_action( 'lsx_content_wrap_before', array( $this, 'search_sidebar' ), 150 );
416
			} else {
417
				$this->has_posts = true;
418
			}
419
		}
420
	}
421
422
	/**
423
	 * Filter the post types.
424
	 */
425
	public function filter_post_types( $query ) {
426
		if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
427
			if ( ! empty( $this->options ) && ! empty( $this->options['display']['search_enable_core'] ) ) {
428
				if ( ! empty( $this->options['general']['search_post_types'] ) && is_array( $this->options['general']['search_post_types'] ) ) {
429
					$post_types = array_keys( $this->options['general']['search_post_types'] );
430
					$query->set( 'post_type', $post_types );
431
				}
432
			}
433
		}
434
	}
435
436
	/**
437
	 * Sets post types with active search options.
438
	 */
439
	public function register_post_types( $post_types ) {
440
		$post_types = array( 'post', 'project', 'service', 'team', 'testimonial', 'video', 'product' );
441
		return $post_types;
442
	}
443
444
	/**
445
	 * Sets taxonomies with active search options.
446
	 */
447
	public function register_taxonomies( $taxonomies ) {
448
		$taxonomies = array( 'category', 'post_tag', 'project-group', 'service-group', 'team_role', 'video-category', 'product_cat', 'product_tag' );
449
		return $taxonomies;
450
	}
451
452
	/**
453
	 * Sets post types with active search options.
454
	 */
455
	public function register_post_type_tabs( $post_types_plural ) {
456
		$post_types_plural = array(
457
			'post' => 'posts',
458
			'project' => 'projects',
459
			'service' => 'services',
460
			'team' => 'team',
461
			'testimonial' => 'testimonials',
462
			'video' => 'videos',
463
			'product' => 'products', // WooCommerce
464
		);
465
		return $post_types_plural;
466
	}
467
468
	/**
469
	 * Enqueue styles and scripts.
470
	 */
471
	public function assets() {
472
		add_filter( 'lsx_defer_parsing_of_js', array( $this, 'skip_js_defer' ), 10, 4 );
473
		wp_enqueue_script( 'touchSwipe', LSX_SEARCH_URL . 'assets/js/vendor/jquery.touchSwipe.min.js', array( 'jquery' ), LSX_SEARCH_VER, true );
474
		wp_enqueue_script( 'slideandswipe', LSX_SEARCH_URL . 'assets/js/vendor/jquery.slideandswipe.min.js', array( 'jquery', 'touchSwipe' ), LSX_SEARCH_VER, true );
475
		wp_enqueue_script( 'lsx-search', LSX_SEARCH_URL . 'assets/js/src/lsx-search.js', array( 'jquery', 'touchSwipe', 'slideandswipe', 'jquery-ui-datepicker' ), LSX_SEARCH_VER, true );
476
477
		$params = apply_filters( 'lsx_search_js_params', array(
478
			'ajax_url' => admin_url( 'admin-ajax.php' ),
479
		));
480
481
		wp_localize_script( 'lsx-search', 'lsx_customizer_params', $params );
482
483
		wp_enqueue_style( 'lsx-search', LSX_SEARCH_URL . 'assets/css/lsx-search.css', array(), LSX_SEARCH_VER );
484
		wp_style_add_data( 'lsx-search', 'rtl', 'replace' );
485
486
		if ( true === $this->new_options ) {
487
			wp_deregister_style( 'lsx_to_search' );
488
			wp_deregister_script( 'lsx_to_search' );
489
		}
490
	}
491
492
	/**
493
	 * Adds the to-search.min.js and the to-search.js
494
	 *
495
	 * @param boolean $should_skip
496
	 * @param string  $tag
497
	 * @param string  $handle
498
	 * @param string  $href
499
	 * @return boolean
500
	 */
501
	public function skip_js_defer( $should_skip, $tag, $handle, $href ) {
502
		if ( ! is_admin() && ( false !== stripos( $href, 'lsx-search.min.js' ) || false !== stripos( $href, 'lsx-search.js' ) ) ) {
503
			$should_skip = true;
504
		}
505
		return $should_skip;
506
	}
507
508
	/**
509
	 * Redirect wordpress to the search template located in the plugin
510
	 *
511
	 * @param	$template
512
	 * @return	$template
513
	 */
514
	public function search_template_include( $template ) {
515
		if ( is_main_query() && is_search() ) {
516
			if ( file_exists( LSX_SEARCH_PATH . 'templates/search.php' ) ) {
517
				$template = LSX_SEARCH_PATH . 'templates/search.php';
518
			}
519
		}
520
521
		return $template;
522
	}
523
524
	/**
525
	 * Ignore sticky posts on Blog search.
526
	 *
527
	 * @param [type] $query
528
	 * @return void
529
	 */
530
	public function ignore_sticky_search( $query ) {
531
		if ( $query->is_main_query() && is_home() ) {
532
			$query->set( 'ignore_sticky_posts', true );
533
		}
534
	}
535
536
	/**
537
	 * Rewrite the search URL
538
	 */
539
	public function pretty_search_redirect() {
540
		global $wp_rewrite,$wp_query;
541
542
		if ( ! isset( $wp_rewrite ) || ! is_object( $wp_rewrite ) || ! $wp_rewrite->using_permalinks() ) {
543
			return;
544
		}
545
546
		$search_base = $wp_rewrite->search_base;
547
548
		if ( is_search() && ! is_admin() && strpos( $_SERVER['REQUEST_URI'], "/{$search_base}/" ) === false ) {
549
			$search_query = get_query_var( 's' );
550
			if ( empty( $search_query ) && isset( $_GET['s'] ) ) {
551
				$search_query = $_GET['s'];
552
			}
553
			$engine = '';
554
555
			// If the search was triggered by a supplemental engine.
556
			if ( isset( $_GET['engine'] ) && 'default' !== $_GET['engine'] ) {
557
				$engine = sanitize_text_field( wp_unslash( $_GET['engine'] ) );
558
				$index  = array_search( $engine, $this->post_type_slugs, true );
559
				if ( false !== $index ) {
560
					$engine = $index;
561
				}
562
				$engine = $engine . '/';
563
			}
564
565
			$get_array = $_GET;
566
567
			if ( is_array( $get_array ) && ! empty( $get_array ) ) {
568
				$vars_to_maintain = array();
569
570
				foreach ( $get_array as $ga_key => $ga_value ) {
571
					if ( false !== strpos( $ga_key, 'fwp_' ) ) {
572
						$vars_to_maintain[] = $ga_key . '=' . $ga_value;
573
					}
574
				}
575
			}
576
577
			$redirect_url = home_url( "/{$search_base}/" . $engine . urlencode( $search_query ) );
578
579
			if ( ! empty( $vars_to_maintain ) ) {
580
				$redirect_url .= '?' . implode( '&', $vars_to_maintain );
581
			}
582
			wp_redirect( $redirect_url );
583
			exit();
584
		}
585
	}
586
587
	/**
588
	 * Parse the Query and trigger a search
589
	 */
590
	public function pretty_search_parse_query( $query ) {
591
		$this->post_type_slugs = array(
592
			'post' => 'posts',
593
			'project' => 'projects',
594
			'service' => 'services',
595
			'team' => 'team',
596
			'testimonial' => 'testimonials',
597
			'video' => 'videos',
598
			'product' => 'products', // WooCommerce
599
		);
600
		if ( $query->is_search() && ! is_admin() && $query->is_main_query() ) {
601
			$search_query = $query->get( 's' );
602
			$keyword_test = explode( '/', $search_query );
603
604
			$index = array_search( $keyword_test[0], $this->post_type_slugs, true );
605
			if ( false !== $index ) {
606
				$engine = $this->post_type_slugs[ $index ];
607
608
				$query->set( 'post_type', $engine );
609
				$query->set( 'engine', $engine );
610
611
				if ( count( $keyword_test ) > 1 ) {
612
					$query->set( 's', $keyword_test[1] );
613
				} elseif ( post_type_exists( $engine ) ) {
614
					$query->set( 's', '' );
615
				}
616
			} else {
617
				if ( isset( $this->options['general']['search_post_types'] ) && is_array( $this->options['general']['search_post_types'] ) ) {
618
					$post_types = array_keys( $this->options['general']['search_post_types'] );
619
					$query->set( 'post_type', $post_types );
620
				}
621
			}
622
		}
623
		return $query;
624
	}
625
626
	/**
627
	 * Change the search slug to /search/ for the JSON+LD output in Yoast SEO
628
	 *
629
	 * @return url
630
	 */
631
	public function change_json_ld_search_url() {
632
		return trailingslashit( home_url() ) . 'search/{search_term_string}';
633
	}
634
635
	/**
636
	 * A filter to set the layout to 2 column.
637
	 */
638
	public function lsx_layout( $layout ) {
639
		if ( ! empty( $this->options['display'][ $this->search_prefix . '_layout' ] ) ) {
640
			if ( false === $this->has_posts ) {
641
				$layout = '1c';
642
			} else {
643
				$layout = $this->options['display'][ $this->search_prefix . '_layout' ];
644
			}
645
		}
646
		return $layout;
647
	}
648
649
	/**
650
	 * Outputs the Search Title Facet
651
	 */
652
	public function search_sidebar_top() {
653
		if ( ! empty( $this->options['display'][ $this->search_prefix . '_facets' ] ) && is_array( $this->options['display'][ $this->search_prefix . '_facets' ] ) && true !== apply_filters( 'lsx_search_hide_search_box', false ) ) {
654
655
			if ( ! is_search() ) {
656
657
				foreach ( $this->options['display'][ $this->search_prefix . '_facets' ] as $facet => $facet_useless ) {
658
659
					if ( isset( $this->facet_data[ $facet ] ) && 'search' === $this->facet_data[ $facet ]['type'] ) {
660
						echo wp_kses_post( '<div class="row">' );
661
							$this->display_facet_default( $facet );
662
						echo wp_kses_post( '</div>' );
663
						unset( $this->options['display'][ $this->search_prefix . '_facets' ][ $facet ] );
664
					}
665
				}
666
			} else {
667
				echo wp_kses_post( '<div class="row">' );
668
					$this->display_facet_search();
669
				echo wp_kses_post( '</div>' );
670
			}
671
		}
672
	}
673
674
	/**
675
	 * Overrides the search facet HTML
676
	 * @param $output
677
	 * @param $params
678
	 *
679
	 * @return string
680
	 */
681
	public function search_facet_html( $output, $params ) {
682
		if ( 'search' == $params['facet']['type'] ) {
683
684
			$value = (array) $params['selected_values'];
685
			$value = empty( $value ) ? '' : stripslashes( $value[0] );
686
			$placeholder = isset( $params['facet']['placeholder'] ) ? $params['facet']['placeholder'] : __( 'Search...', 'lsx-search' );
687
			$placeholder = facetwp_i18n( $placeholder );
688
689
			ob_start();
690
			?>
691
			<div class="col-xs-12 facetwp-item facetwp-form">
692
				<div class="search-form lsx-search-form 2">
693
					<div class="input-group facetwp-search-wrap">
694
						<div class="field">
695
							<input class="facetwp-search search-field form-control" type="text" placeholder="<?php echo esc_attr( $placeholder ); ?>" autocomplete="off" value="<?php echo esc_attr( $value ); ?>">
696
						</div>
697
698
						<div class="field submit-button">
699
							<button class="search-submit btn facetwp-btn" type="submit"><?php esc_html_e( 'Search', 'lsx-search' ); ?></button>
700
						</div>
701
					</div>
702
				</div>
703
			</div>
704
			<?php
705
			$output = ob_get_clean();
706
		}
707
		return $output;
708
	}
709
710
	/**
711
	 * Change the primary and secondary column classes.
712
	 */
713
	public function lsx_layout_selector( $return_class, $class, $layout, $size ) {
714
		if ( ! empty( $this->options['display'][ $this->search_prefix . '_layout' ] ) ) {
715
716
			if ( '2cl' === $layout || '2cr' === $layout ) {
717
				$main_class    = 'col-sm-8 col-md-9';
718
				$sidebar_class = 'col-sm-4 col-md-3';
719
720
				if ( '2cl' === $layout ) {
721
					$main_class    .= ' col-sm-pull-4 col-md-pull-3 search-sidebar-left';
722
					$sidebar_class .= ' col-sm-push-8 col-md-push-9';
723
				}
724
725
				if ( 'main' === $class ) {
726
					return $main_class;
727
				}
728
729
				if ( 'sidebar' === $class ) {
730
					return $sidebar_class;
731
				}
732
			}
733
		}
734
735
		return $return_class;
736
	}
737
738
	/**
739
	 * Displays the Alphabet sorter above the facets.
740
	 *
741
	 * @return void
742
	 */
743
	public function display_alphabet_facet() {
744
		if ( isset( $this->options['display'][ $this->search_prefix . '_az_pagination' ] ) ) {
745
			$az_pagination = $this->options['display'][ $this->search_prefix . '_az_pagination' ];
746
		} else {
747
			$az_pagination = false;
748
		}
749
		$az_pagination = apply_filters( 'lsx_search_top_az_pagination', $az_pagination );
750
		if ( false !== $az_pagination && '' !== $az_pagination ) {
751
			echo do_shortcode( '[facetwp facet="' . $az_pagination . '"]' );
752
		}
753
	}
754
755
	/**
756
	 * Outputs top.
757
	 */
758
	public function facet_top_bar() {
759
		if ( true === apply_filters( 'lsx_search_hide_top_bar', false ) ) {
760
			return;
761
		}
762
763
		$show_pagination     = true;
764
		$pagination_visible  = false;
765
		$show_per_page_combo = empty( $this->options['display'][ $this->search_prefix . '_disable_per_page' ] );
766
		$show_sort_combo     = empty( $this->options['display'][ $this->search_prefix . '_disable_sorting' ] );
767
768
		$show_pagination     = apply_filters( 'lsx_search_top_show_pagination', $show_pagination );
769
		$pagination_visible  = apply_filters( 'lsx_search_top_pagination_visible', $pagination_visible );
770
		$show_per_page_combo = apply_filters( 'lsx_search_top_show_per_page_combo', $show_per_page_combo );
771
		$show_sort_combo     = apply_filters( 'lsx_search_top_show_sort_combo', $show_sort_combo );
772
		$facet_row_classes   = apply_filters( 'lsx_search_top_facetwp_row_classes', '' );
773
		?>
774
		<div id="facetwp-top">
775
			<?php if ( $show_sort_combo || ( $show_pagination && $show_per_page_combo ) ) { ?>
776
				<div class="row facetwp-top-row-1 hidden-xs <?php echo esc_attr( $facet_row_classes ); ?>">
777
					<div class="col-xs-12">
778
779
						<?php if ( ! empty( $this->options['display'][ $this->search_prefix . '_display_result_count' ] ) && false === apply_filters( 'lsx_search_hide_result_count', false ) ) { ?>
780
							<div class="row">
781
								<div class="col-md-12 facetwp-item facetwp-results">
782
									<h3 class="lsx-search-title lsx-search-title-results"><?php esc_html_e( 'Results', 'lsx-search' ); ?> <?php echo '(' . do_shortcode( '[facetwp counts="true"]' ) . ')&nbsp;'; ?>
783
									<?php if ( false !== $this->options && isset( $this->options['display'] ) && ( ! empty( $this->options['display'][ $this->search_prefix . '_display_clear_button' ] ) ) && 'on' === $this->options['display'][ $this->search_prefix . '_display_clear_button' ] ) { ?>
784
										<span class="clear-facets hidden">- <a title="<?php esc_html_e( 'Clear the current search filters.', 'lsx-search' ); ?>" class="facetwp-results-clear" type="button" onclick="<?php echo esc_attr( apply_filters( 'lsx_search_clear_function', 'lsx_search.clearFacets(this);' ) ); ?>"><?php esc_html_e( 'Clear', 'lsx-search' ); ?></a></span>
785
									<?php } ?>
786
									</h3>
787
								</div>
788
							</div>
789
						<?php } ?>
790
791
						<?php do_action( 'lsx_search_facetwp_top_row' ); ?>
792
793
						<?php $this->display_alphabet_facet(); ?>
794
795
						<?php
796
						if ( $show_sort_combo ) { 
797
							$new_sorter = $this->has_facet( 'sort' );
798
							if ( false !== $new_sorter ) {
799
								echo do_shortcode( '[facetwp facet="' . $new_sorter . '"]' );
800
							} else {
801
								echo do_shortcode( '[facetwp sort="true"]' );
802
							}	
0 ignored issues
show
Spaces must be used for mid-line alignment; tabs are not allowed
Loading history...
803
						}
804
						?>
805
					</div>
806
				</div>
807
			<?php } ?>
808
		</div>
809
		<?php
810
	}
811
812
	public function has_facet( $type ) {
0 ignored issues
show
Method name "Frontend::has_facet" is not in camel caps format
Loading history...
813
		$has_facet = false;
814
		if ( ! empty( $this->options['display'][ $this->search_prefix . '_facets' ] ) && is_array( $this->options['display'][ $this->search_prefix . '_facets' ] ) ) {
815
			foreach ( $this->options['display'][ $this->search_prefix . '_facets' ] as $facet => $facet_useless ) {
816
				if ( isset( $this->facet_data[ $facet ] ) &&  $this->facet_data[ $facet ]['type'] === $type ) {
0 ignored issues
show
Expected 1 space after "&&"; 2 found
Loading history...
Expected 1 space after logical operator; 2 found
Loading history...
817
					$has_facet = $facet;
818
				}
819
			}
820
		}
821
		return $has_facet;
822
	}
823
824
	/**
825
	 * Outputs bottom.
826
	 */
827
	public function facet_bottom_bar() {
828
		if ( true === apply_filters( 'lsx_search_hide_bottom_bar', false ) ) {
829
			return;
830
		}
831
		$show_pagination    = true;
832
		$pagination_visible = false;
833
		if ( isset( $this->options['display'][ $this->search_prefix . '_az_pagination' ] ) ) {
834
			$az_pagination = $this->options['display'][ $this->search_prefix . '_az_pagination' ];
835
		} else {
836
			$az_pagination = false;
837
		}
838
839
		$show_per_page_combo = empty( $this->options['display'][ $this->search_prefix . '_disable_per_page' ] );
840
		$show_sort_combo     = empty( $this->options['display'][ $this->search_prefix . '_search_disable_sorting' ] );
841
842
		$show_pagination     = apply_filters( 'lsx_search_bottom_show_pagination', $show_pagination );
843
		$pagination_visible  = apply_filters( 'lsx_search_bottom_pagination_visible', $pagination_visible );
844
		$show_per_page_combo = apply_filters( 'lsx_search_bottom_show_per_page_combo', $show_per_page_combo );
845
		$show_sort_combo     = apply_filters( 'lsx_search_bottom_show_sort_combo', $show_sort_combo );
846
847
		if ( $show_pagination || ! empty( $az_pagination ) ) { ?>
848
			<div id="facetwp-bottom">
849
				<div class="row facetwp-bottom-row-1">
850
					<div class="col-xs-12">
851
						<?php do_action( 'lsx_search_facetwp_bottom_row' ); ?>
852
853
						<?php //if ( $show_sort_combo ) { ?>
854
							<?php //echo do_shortcode( '[facetwp sort="true"]' ); ?>
855
						<?php //} ?>
856
857
						<?php //if ( ( $show_pagination && $show_per_page_combo ) || $show_per_page_combo ) { ?>
858
							<?php //echo do_shortcode( '[facetwp per_page="true"]' ); ?>
859
						<?php //} ?>
860
861
						<?php
862
						if ( $show_pagination ) {
863
							$output_pagination = do_shortcode( '[facetwp pager="true"]' );
864
							if ( ! empty( $this->options['display'][ $this->search_prefix . '_facets' ] ) && is_array( $this->options['display'][ $this->search_prefix . '_facets' ] ) ) {
865
								foreach ( $this->options['display'][ $this->search_prefix . '_facets' ] as $facet => $facet_useless ) {
866
									if ( isset( $this->facet_data[ $facet ] ) && in_array( $this->facet_data[ $facet ]['type'], array( 'pager' ) ) ) {
867
										$output_pagination = do_shortcode( '[facetwp facet="pager_"]' );
868
									}
869
								}
870
							}
871
							echo wp_kses_post( $output_pagination );
872
						?>
873
						<?php } ?>
874
					</div>
875
				</div>
876
			</div>
877
		<?php }
878
	}
879
880
	/**
881
	 * Adds in the closing facetwp div
882
	 *
883
	 * @return void
884
	 */
885
	public function facetwp_tempate_open() {
886
		?>
887
		<div class="facetwp-template">
888
		<?php
889
	}
890
891
	/**
892
	 * Adds in the closing facetwp div
893
	 *
894
	 * @return void
895
	 */
896
	public function facetwp_tempate_close() {
897
		?>
898
		</div>
899
		<?php
900
	}
901
902
	/**
903
	 * Disables default sidebar.
904
	 */
905
	public function lsx_sidebar_enable( $sidebar_enabled ) {
906
		$sidebar_enabled = false;
907
		return $sidebar_enabled;
908
	}
909
910
	/**
911
	 * Outputs custom sidebar.
912
	 */
913
	public function search_sidebar() {
914
915
		$this->options = apply_filters( 'lsx_search_sidebar_options', $this->options );
916
		?>
917
			<?php do_action( 'lsx_search_sidebar_before' ); ?>
918
919
			<div id="secondary" class="facetwp-sidebar widget-area <?php echo esc_attr( lsx_sidebar_class() ); ?>" role="complementary">
920
921
				<?php do_action( 'lsx_search_sidebar_top' ); ?>
922
923
				<?php if ( ! empty( $this->options['display'][ $this->search_prefix . '_facets' ] ) && is_array( $this->options['display'][ $this->search_prefix . '_facets' ] ) ) { ?>
924
					<div class="row facetwp-row lsx-search-filer-area">
925
						<h3 class="facetwp-filter-title"><?php echo esc_html_e( 'Refine by', 'lsx-search' ); ?></h3>
926
						<div class="col-xs-12 facetwp-item facetwp-filters-button hidden-sm hidden-md hidden-lg">
927
							<button class="ssm-toggle-nav btn btn-block" rel="lsx-search-filters"><?php esc_html_e( 'Filters', 'lsx-search' ); ?> <i class="fa fa-chevron-down" aria-hidden="true"></i></button>
928
						</div>
929
930
						<div class="ssm-overlay ssm-toggle-nav" rel="lsx-search-filters"></div>
931
932
						<div class="col-xs-12 facetwp-item-wrap facetwp-filters-wrap" id="lsx-search-filters">
933
							<div class="row hidden-sm hidden-md hidden-lg ssm-row-margin-bottom">
934
								<div class="col-xs-12 facetwp-item facetwp-filters-button">
935
									<button class="ssm-close-btn ssm-toggle-nav btn btn-block" rel="lsx-search-filters"><?php esc_html_e( 'Close Filters', 'lsx-search' ); ?> <i class="fa fa-times" aria-hidden="true"></i></button>
936
								</div>
937
							</div>
938
939
							<div class="row">
940
								<?php
941
								// Slider.
942
								foreach ( $this->options['display'][ $this->search_prefix . '_facets' ] as $facet => $facet_useless ) {
943
									if ( isset( $this->facet_data[ $facet ] ) && ! in_array( $this->facet_data[ $facet ]['type'], array( 'alpha', 'search', 'pager', 'sort', 'autocomplete' ) ) ) {
944
										$this->display_facet_default( $facet );
945
									}
946
								}
947
								?>
948
							</div>
949
950
							<div class="row hidden-sm hidden-md hidden-lg ssm-row-margin-top">
951
								<div class="col-xs-12 facetwp-item facetwp-filters-button">
952
									<button class="ssm-apply-btn ssm-toggle-nav btn btn-block" rel="lsx-search-filters"><?php esc_html_e( 'Apply Filters', 'lsx-search' ); ?> <i class="fa fa-check" aria-hidden="true"></i></button>
953
								</div>
954
							</div>
955
						</div>
956
					</div>
957
				<?php } ?>
958
959
				<?php do_action( 'lsx_search_sidebar_bottom' ); ?>
960
			</div>
961
962
			<?php do_action( 'lsx_search_sidebar_after' ); ?>
963
		<?php
964
	}
965
966
	/**
967
	 * Check if the pager facet is on
968
	 *
969
	 * @return void
970
	 */
971
	public function pager_facet_enabled() {
972
973
		$pager_facet_off = false;
974
975
		if ( ! empty( $this->options['display'][ $this->search_prefix . '_facets' ] ) && is_array( $this->options['display'][ $this->search_prefix . '_facets' ] ) ) {
976
			foreach ( $this->options['display'][ $this->search_prefix . '_facets' ] as $facet => $facet_useless ) {
977
				if ( isset( $this->facet_data[ $facet ] ) && ! in_array( $this->facet_data[ $facet ]['type'], array( 'pager' ) ) ) {
978
					$pager_facet_off = true;
979
				}
980
			}
981
		}
982
983
		return $pager_facet_off;
984
	}
985
986
	/**
987
	 * Display facet search.
988
	 */
989
	public function display_facet_search() {
990
		?>
991
		<div class="col-xs-12 facetwp-item facetwp-form">
992
			<form class="search-form lsx-search-form" action="<?php echo esc_attr( home_url() ); ?>" method="get">
993
				<div class="input-group">
994
					<div class="field">
995
						<input class="facetwp-search search-field form-control" name="s" type="search" placeholder="<?php esc_html_e( 'Search', 'lsx-search' ); ?>..." autocomplete="off" value="<?php echo get_search_query() ?>">
996
					</div>
997
998
					<div class="field submit-button">
999
						<button class="search-submit btn" type="submit"><?php esc_html_e( 'Search', 'lsx-search' ); ?></button>
1000
					</div>
1001
				</div>
1002
			</form>
1003
		</div>
1004
		<?php
1005
	}
1006
1007
	/**
1008
	 * Display facet default.
1009
	 */
1010
	public function display_facet_default( $facet ) {
1011
1012
		$show_collapse = ! isset( $this->options['display'][$this->search_prefix . '_collapse'] ) || 'on' !== $this->options['display'][$this->search_prefix . '_collapse'];
1013
		$col_class = '';
1014
1015
		if ( 'search' === $this->facet_data[ $facet ]['type'] ) : ?>
1016
			<?php echo do_shortcode( '[facetwp facet="' . $facet . '"]' ); ?>
1017
		<?php else : ?>
1018
			<div class="col-xs-12 facetwp-item parent-facetwp-facet-<?php echo esc_html( $facet ); ?> <?php echo esc_attr( $col_class ); ?>">
1019
				<?php if ( ! $show_collapse ) { ?>
1020
					<div class="facetwp-collapsed">
1021
						<h3 class="lsx-search-title"><?php echo wp_kses_post( $this->facet_data[ $facet ]['label'] ); ?></h3>
1022
						<button title="<?php echo esc_html_e( 'Click to Expand', 'lsx-search' ); ?>" class="facetwp-collapse" type="button" data-toggle="collapse" data-target="#collapse-<?php echo esc_html( $facet ); ?>" aria-expanded="false" aria-controls="collapse-<?php echo esc_html( $facet ); ?>"></button>
1023
					</div>
1024
					<div id="collapse-<?php echo esc_html( $facet ); ?>" class="collapse">
1025
						<?php echo do_shortcode( '[facetwp facet="' . $facet . '"]' ); ?>
1026
					</div>
1027
				<?php } else { ?>
1028
					<h3 class="lsx-search-title"><?php echo wp_kses_post( $this->facet_data[ $facet ]['label'] ); ?></h3>
1029
					<?php echo do_shortcode( '[facetwp facet="' . $facet . '"]' ); ?>
1030
				<?php } ?>
1031
			</div>
1032
		<?php
1033
		endif;
1034
	}
1035
1036
	/**
1037
	 * Changes slot column class.
1038
	 */
1039
	public function change_slot_column_class( $class ) {
1040
		if ( is_post_type_archive( 'video' ) || is_tax( 'video-category' ) ) {
1041
			$column_class = 'col-xs-12 col-sm-4';
1042
		}
1043
1044
		return $column_class;
1045
	}
1046
1047
	/**
1048
	 * Add post type label to the title.
1049
	 */
1050
	public function add_label_to_title() {
1051
		if ( is_search() ) {
1052
			if ( ! empty( $this->options['display']['engine_search_enable_pt_label'] ) ) {
1053
				$post_type = get_post_type();
1054
				$post_type = str_replace( '_', ' ', $post_type );
1055
				$post_type = str_replace( '-', ' ', $post_type );
1056
				if ( 'tribe events' === $post_type ) {
1057
					$post_type = 'Events';
1058
				}
1059
				echo wp_kses_post( ' <span class="label label-default lsx-label-post-type">' . $post_type . '</span>' );
1060
			}
1061
		}
1062
	}
1063
1064
	/**
1065
	 * Changes the sort options.
1066
	 */
1067
	public function facetwp_sort_options( $options, $params ) {
1068
		$this->set_vars();
1069
1070
		if ( true === $this->search_enabled ) {
1071
			if ( 'default' !== $params['template_name'] && 'wp' !== $params['template_name'] ) {
1072
				return $options;
1073
			}
1074
1075
			if ( ! empty( $this->options['display'][ $this->search_prefix . '_disable_date' ] ) ) {
1076
				unset( $options['date_desc'] );
1077
				unset( $options['date_asc'] );
1078
			}
1079
1080
			if ( ! empty( $this->options['display'][ $this->search_prefix . '_disable_az_sorting' ] ) ) {
1081
				unset( $options['title_desc'] );
1082
				unset( $options['title_asc'] );
1083
			}
1084
		}
1085
1086
		return $options;
1087
	}
1088
1089
	/**
1090
	 * @param $allowedtags
1091
	 * @param $context
1092
	 *
1093
	 * @return mixed
1094
	 */
1095
	public function kses_allowed_html( $allowedtags, $context ) {
1096
		$allowedtags['a']['data-value'] = true;
1097
		$allowedtags['a']['data-selection']  = true;
1098
		$allowedtags['button']['data-toggle'] = true;
1099
		return $allowedtags;
1100
	}
1101
1102
	/**
1103
	 * Change FaceWP result count HTML
1104
	 */
1105
	public function get_search_query( $keyword ) {
1106
		global $wp_rewrite,$wp_query;
1107
1108
		if ( empty( $keyword ) ) {
1109
			if ( ! isset( $wp_rewrite ) || ! is_object( $wp_rewrite ) || ! $wp_rewrite->using_permalinks() ) {
1110
				return;
1111
			}
1112
			$search_base = $wp_rewrite->search_base;
1113
			if ( strpos( $_SERVER['REQUEST_URI'], "/{$search_base}/" ) !== false ) {
1114
				$words = explode( "/{$search_base}/", $_SERVER['REQUEST_URI'] );
1115
				$limit = count( $words );
1116
				if ( isset( $words[ $limit - 1 ] ) ) {
1117
					$keyword = $words[ $limit - 1 ];
1118
				}
1119
			}
1120
		}
1121
1122
		$needle = trim( '/ ' );
1123
		$words = explode( $needle, $keyword );
1124
		if ( is_array( $words ) && ! empty( $words ) ) {
1125
			$keyword = $words[ count( $words ) - 1 ];
1126
		}
1127
		$keyword = str_replace( '+', ' ', $keyword );
1128
		$keyword = str_replace( '%20', ' ', $keyword );
1129
		return $keyword;
1130
	}
1131
}
1132