PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.4.0
ShopBuilder – WooCommerce Builder For Elementor v3.4.0
3.4.2 3.4.1 3.4.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 All 63 releases
← All changes | app/Controllers/Admin/Ajax/ModalTemplate.php +154 -86 2.2.03.4.0 View file →
@@ -37,9 +37,9 @@
37 37 * Popups For Create Template
38 38 *
39 39 * @return void
40 40 */
41 - public function response() {
41 + public function response() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded
42 42 $title = '<h2>' . esc_html__( 'Template Settings', 'shopbuilder' ) . '</h2>';
43 43 if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
44 44 $return = [
45 45 'success' => false,
@@ -56,9 +56,18 @@
56 56 'content' => esc_html__( 'Permission Denied...', 'shopbuilder' ),
57 57 ];
58 58 wp_send_json( $return );
59 59 }
60 + if ( ! defined( 'ELEMENTOR_VERSION' ) ) {
61 + $return = [
62 + 'success' => true,
63 + 'title' => $title,
64 + 'content' => '<h2 style="text-align: center;">' . esc_html__( 'Permission Denied. Please Install elementor', 'shopbuilder' ) . '</h2>',
65 + ];
60 66
67 + wp_send_json( $return );
68 + }
69 +
61 70 add_filter( 'option_' . Uploads_Manager::UNFILTERED_FILE_UPLOADS_KEY, '__return_true' );
62 71 Plugin::$instance->files_manager->clear_cache();
63 72
64 73 // user capability check.
@@ -64,19 +73,20 @@
64 73 // user capability check.
65 74 $user = wp_get_current_user();
66 75 $allowed_roles = [ 'editor', 'administrator', 'author' ];
67 76
68 - if ( ! array_intersect( $allowed_roles, $user->roles ) ) {
77 + if ( ! array_intersect( $allowed_roles, Fns::get_current_user_roles() ) ) {
69 78 wp_die( esc_html__( 'You don\'t have permission to perform this action', 'shopbuilder' ) );
70 79 }
71 80
72 81 // Check if the user is not logged in and the provided 'user_id' in the request does not match the currently logged-in user's ID.
82 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.PHP.YodaConditions.NotYoda
73 83 if ( ! is_user_logged_in() && $user->ID !== sanitize_text_field( $_REQUEST['user_id'] ) ) {
74 84 wp_die( esc_html__( 'You don\'t have proper authorization to perform this action', 'shopbuilder' ) );
75 85 }
76 86
77 - $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : null;
78 - $layout_id = isset( $_POST['layout_id'] ) ? absint( $_POST['layout_id'] ) : null;
87 + $post_id = isset( $_REQUEST['post_id'] ) ? absint( $_REQUEST['post_id'] ) : null;
88 + $layout_id = isset( $_REQUEST['layout_id'] ) ? absint( $_REQUEST['layout_id'] ) : null;
79 89
80 90 $template_type = null;
81 91 $product_page_for = 'all_products';
82 92 $template_default = null;
@@ -94,9 +104,9 @@
94 104 if ( rtsb()->has_pro() ) {
95 105 $product_page_for = get_post_meta( $post_id, '_is_product_page_template_for', true );
96 106 }
97 107
98 - // TODO:: This Condition Will remove after release Gutenberg Addons.
108 + /* This Condition Will remove after release Gutenberg Addons. */
99 109 if ( 'gutenberg' == $edit_by ) {
100 110 $action = 'elementor';
101 111 $edit_by = 'elementor';
102 112 }
@@ -114,20 +124,8 @@
114 124 );
115 125
116 126 $_rtsb_import_id = get_post_meta( $post_id, '_rtsb_import_id', true );
117 127 }
118 -
119 - $status = $_REQUEST['status'] ?? '';
120 - $post_args = [ 'timeout' => 120 ];
121 - $post_args['body'] = [
122 - 'status' => $status,
123 - ];
124 - $layoutRequest = wp_remote_post( rtsb()->BASE_API, $post_args );
125 - $layoutData = [];
126 - if ( ! is_wp_error( $layoutRequest ) && ! empty( $layoutRequest['body'] ) ) {
127 - $layoutData = json_decode( $layoutRequest['body'], true );
128 - }
129 -
130 128 ob_start();
131 129
132 130 ?>
133 131 <form action="<?php echo esc_url( admin_url( 'edit.php?post_type=rtsb_builder' ) ); ?>" autocomplete="off" data-imported-id="<?php echo esc_attr( $_rtsb_import_id ); ?>">
@@ -174,11 +172,18 @@
174 172 <?php
175 173 $builder_page_types = [
176 174 'all_products' => esc_html__( 'All Products', 'shopbuilder' ),
177 175 'product_cats' => esc_html__( 'Product Categories', 'shopbuilder' ),
176 + 'product_brands' => esc_html__( 'Product Brands', 'shopbuilder' ),
178 177 'product_tags' => esc_html__( 'Product Tags', 'shopbuilder' ),
179 178 'specific_products' => esc_html__( 'Selected Products', 'shopbuilder' ),
180 179 ];
180 + // Only expose the brand option when the `product_brand` taxonomy is
181 + // registered (WC 9.4+ native, or a brand plugin). Hides gracefully
182 + // on sites without brand support.
183 + if ( ! taxonomy_exists( 'product_brand' ) ) {
184 + unset( $builder_page_types['product_brands'] );
185 + }
181 186 foreach ( $builder_page_types as $key => $value ) {
182 187 ?>
183 188 <option <?php echo esc_attr( $key === $product_page_for ? 'selected="selected"' : '' ); ?> value="<?php echo esc_attr( $key ); ?>"> <?php echo esc_html( $value ); ?> </option>
184 189 <?php } ?>
@@ -184,8 +189,15 @@
184 189 <?php } ?>
185 190 </select>
186 191 </div>
187 192
193 + <?php if ( ! rtsb()->has_pro() ) { ?>
194 + <div class="rtsb-product-page-for rtsb-tb-field-wraper" style="display:none;" >
195 + <label for="product_page_for"> </label>
196 + <span class="elementor-pro-notice"><a target="_blank" href="<?php echo esc_url( rtsb()->pro_version_link() ); ?>">Upgrade to PRO</a> to unlock Product Categories, Product Tags, Selected Products</span>
197 + </div>
198 + <?php } ?>
199 +
188 200 <!-- Product Page For Categories -->
189 201 <div class="rtsb-categories-page-field rtsb-product-page-for-the-categories rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;">
190 202 <?php
191 203 $default_items_link = '';
@@ -226,8 +238,15 @@
226 238 ?>
227 239 </p>
228 240 </div>
229 241
242 + <?php if ( ! rtsb()->has_pro() ) { ?>
243 + <div class="rtsb-categories-page-field rtsb-product-page-for-the-categories rtsb-tb-field-wraper" style="display:none;">
244 + <label for="product_page_for"> </label>
245 + <span class="elementor-pro-notice"><a target="_blank" href="<?php echo esc_url( rtsb()->pro_version_link() ); ?>">Upgrade to PRO</a> to unlock Categories Base Prodcut Page.</span>
246 + </div>
247 + <?php } ?>
248 +
230 249 <!-- Product Page for Selected Product Tags-->
231 250 <div class="rtsb-product-tags-page-field rtsb-product-page-for-the-tags rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;">
232 251 <?php
233 252 $default_items_link = '';
@@ -269,8 +288,64 @@
269 288 </p>
270 289 </div>
271 290
272 291
292 + <!-- Product Page for Selected Product Brands -->
293 + <?php if ( taxonomy_exists( 'product_brand' ) ) : ?>
294 + <div class="rtsb-product-brands-page-field rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;">
295 + <?php
296 + $default_items_link = '';
297 + $default_items = '';
298 + $brands_name = apply_filters( 'rtsb/template/builder/selected/brands', [], $post_id, $template_type );
299 + if ( ! empty( $brands_name ) && is_array( $brands_name ) ) {
300 + foreach ( $brands_name as $b_name ) {
301 + $brand = get_term_by( 'slug', $b_name, 'product_brand' );
302 + if ( empty( $brand ) || is_wp_error( $brand ) ) {
303 + continue;
304 + }
305 + $title_brand = $brand->name;
306 + $link = get_term_link( $brand );
307 + if ( ! is_wp_error( $link ) ) {
308 + $default_items_link .= '<a target="_blank" href="' . esc_url( $link ) . '">' . esc_html( $title_brand ) . '</a>';
309 + }
310 + $default_items .= '<option selected="selected" value="' . esc_attr( $b_name ) . '">' . esc_html( $title_brand ) . '</option>';
311 + }
312 + }
313 + ?>
314 + <label for="rtsb_page_for_the_product_brands">
315 + <?php esc_html_e( 'Select Product Brands', 'shopbuilder' ); ?>
316 + <?php if ( ! rtsb()->has_pro() ) { ?>
317 + <div class="card-label">
318 + <span class="rtsb-btn-import pro-btn">
319 + <?php echo esc_html( 'PRO' ); ?>
320 + </span>
321 + </div>
322 + <?php } ?>
323 + </label>
324 + <select class="rtsb-field" id="rtsb_page_for_the_product_brands" name="rtsb_page_for_the_product_brands" multiple="multiple">
325 + <?php Fns::print_html( $default_items, true ); ?>
326 + </select>
327 + <p style="margin:0;">Select a Product Brand to apply this template. You can select multiple Brands. Keep it blank to apply to all.
328 + <?php
329 + if ( ! empty( $default_items_link ) ) {
330 + ?>
331 + <span style="display: flex; gap: 3px 7px; flex-wrap: wrap; margin-top: 10px;"> <?php Fns::print_html( 'View Brand Archive Pages: ' . $default_items_link ); ?> </span>
332 + <?php
333 + }
334 + ?>
335 + </p>
336 + </div>
337 +
338 + <?php if ( ! rtsb()->has_pro() ) { ?>
339 + <div class="rtsb-product-brands-page-field rtsb-tb-field-wraper" style="display:none;">
340 + <label for="product_page_for"> </label>
341 + <span class="elementor-pro-notice"><a target="_blank" href="<?php echo esc_url( rtsb()->pro_version_link() ); ?>">Upgrade to PRO</a> to unlock Brand Base Product Page.</span>
342 + </div>
343 + <?php } ?>
344 + <?php endif; ?>
345 +
346 + <?php do_action( 'rtsb/builder/modal/extra_fields', $post_id, $template_type, $product_page_for ); ?>
347 +
273 348 <!-- Product Page for Selected Product -->
274 349 <div class="rtsb-page-for-the-products rtsb-tb-field-wraper <?php echo esc_attr( ! rtsb()->has_pro() ? 'pro-disable' : '' ); ?>" style="display:none;">
275 350 <?php
276 351 $default_items_link = '';
@@ -310,11 +385,14 @@
310 385 <div class="rtsb-product-page-preview-field rtsb-tb-field-wraper" style="display:none;">
311 386 <?php
312 387 $default_items = '';
313 388 $product_id = get_post_meta( $post_id, BuilderFns::$product_template_meta, true );
314 - if ( $product_id ) {
389 + if ( $product_id && get_post_status( $product_id ) ) {
315 390 $default_items = '<option selected="selected" value="' . $product_id . '">' . get_the_title( $product_id ) . ' - ( ID ' . $product_id . ' )</option>';
316 391 }
392 + if ( $product_id && ! get_post_status( $product_id ) ) {
393 + delete_post_meta( $post_id, BuilderFns::$product_template_meta );
394 + }
317 395 ?>
318 396 <label for="rtsb_product_page_preview"><?php esc_html_e( 'Select Preview Product', 'shopbuilder' ); ?></label>
319 397 <select class="rtsb-field" id="rtsb_product_page_preview" name="rtsb_product_page_preview">
320 398 <?php Fns::print_html( $default_items, true ); ?>
@@ -334,8 +412,16 @@
334 412 </div>
335 413 <div class="rtsb-template-setdefaults rtsb-tb-field-wraper">
336 414 <label for="default_template"> <?php esc_html_e( 'Set as Active Template', 'shopbuilder' ); ?></label>
337 415 <?php
416 + $singleton_types = apply_filters(
417 + 'rtsb/builder/singleton_types',
418 + array_keys( BuilderFns::builder_page_types() )
419 + );
420 + $is_pool_type = $template_type && ! in_array( $template_type, $singleton_types, true );
421 + if ( $post_id && $is_pool_type ) {
422 + $template_default = 'on' === get_post_meta( $post_id, '_rtsb_tb_enabled_in_pool', true ) ? $post_id : 0;
423 + }
338 424 if ( $post_id && 'product' === $template_type ) {
339 425 if ( 'specific_products' === $product_page_for ) {
340 426 $set_default = BuilderFns::get_specific_product_as_default( $post_id );
341 427 if ( $set_default ) {
@@ -340,8 +426,11 @@
340 426 $set_default = BuilderFns::get_specific_product_as_default( $post_id );
341 427 if ( $set_default ) {
342 428 $template_default = $post_id;
343 429 }
430 + if ( ! $set_default && $template_default === $post_id ) {
431 + $template_default = '';
432 + }
344 433 } else {
345 434 $set_default_option_name = '';
346 435 if ( 'product_cats' === $product_page_for ) {
347 436 $set_default_option_name = BuilderFns::option_name_product_page_specific_cat_set_default( $post_id );
@@ -346,10 +435,12 @@
346 435 if ( 'product_cats' === $product_page_for ) {
347 436 $set_default_option_name = BuilderFns::option_name_product_page_specific_cat_set_default( $post_id );
348 437 } elseif ( 'product_tags' === $product_page_for ) {
349 438 $set_default_option_name = BuilderFns::option_name_product_page_specific_tag_set_default( $post_id );
439 + } elseif ( 'product_brands' === $product_page_for ) {
440 + $set_default_option_name = BuilderFns::option_name_product_page_specific_brand_set_default( $post_id );
350 441 }
351 - $default_id = TemplateSettings::instance()->get_option( $set_default_option_name );
442 + $default_id = ! empty( $set_default_option_name ) && TemplateSettings::instance()->get_option( $set_default_option_name );
352 443 if ( $default_id ) {
353 444 $template_default = $post_id;
354 445 }
355 446 }
@@ -357,11 +448,19 @@
357 448 $categories_name = apply_filters( 'rtsb/template/builder/selected/categories', [], $post_id, $template_type );
358 449 $set_default = BuilderFns::get_specific_category_as_default( $post_id );
359 450 if ( ! empty( $categories_name ) && $set_default ) {
360 451 $template_default = $post_id;
452 + } else {
453 + $option_name = BuilderFns::option_name( $template_type );
454 + $is_set_default = TemplateSettings::instance()->get_option( $option_name );
455 + $set_default = $is_set_default;
361 456 }
457 + if ( ! $set_default && $template_default === $post_id ) {
458 + $template_default = '';
459 + }
362 460 }
363 461
462 + $template_default = apply_filters( 'rtsb/builder/modal/template_default', $template_default, $post_id, $template_type );
364 463 ?>
365 464 <span class="rtsb-switch-wrapper"
366 465 title="<?php esc_html_e( 'Switch on to set as active template', 'shopbuilder' ); ?>">
367 466 <label class="rtsb-switch">
@@ -369,9 +468,9 @@
369 468 type="checkbox"
370 469 id="default_template"
371 470 name="default_template"
372 471 value="default_template"
373 - <?php echo esc_attr( ( $post_id && absint( $post_id ) === absint( $template_default ) ) ? 'checked' : '' ); ?>
472 + <?php echo esc_attr( ( $post_id && ( absint( $post_id ) === absint( $template_default ) ) ) ? 'checked' : '' ); ?>
374 473 >
375 474 <span class="rtsb-slider rtsb-round ">
376 475 <span class="rtsb-loader"></span>
377 476 </span>
@@ -378,32 +477,29 @@
378 477 </label>
379 478 </span>
380 479 </div>
381 480 <!-- TODO: Moday Layout -->
382 - <?php if ( ! $post_id ) { ?>
383 - <div class="set-default-layout-wrapper rtsb-tb-field-wraper">
384 - <label>
385 - <?php esc_html_e( 'Pre-built Templates ', 'shopbuilder' ); ?>
386 - <span id="modallabelPrefix"></span>
387 - </label>
388 - <div class="set-default-layout">
389 - <?php
390 - $default_item = [
391 - 'template_type' => 'default',
392 - 'image_url' => \Elementor\Utils::get_placeholder_image_src(),
393 - 'preview_link' => '',
394 - 'title' => __( 'Blank Template', 'shopbuilder' ),
395 - ];
396 -
397 - $this->get_modal_card_html( $default_item );
398 -
399 - if ( ! empty( $layoutData['layouts'] ) ) {
400 - foreach ( $layoutData['layouts'] as $item ) {
401 - $this->get_modal_card_html( $item );
402 - }
403 - }
404 - ?>
481 + <?php
482 + if ( ! $post_id ) {
483 + if ( defined( 'ELEMENTOR_PATH' ) && class_exists( '\Elementor\Utils' ) ) {
484 + $placeholderImageSrc = \Elementor\Utils::get_placeholder_image_src();
485 + } else {
486 + $placeholderImageSrc = '#';
487 + }
488 + ?>
489 + <div class="set-default-layout-wrapper rtsb-tb-field-wraper" style="opacity: 0" >
490 + <div style="display: flex; justify-content: space-between;">
491 + <label>
492 + <?php esc_html_e( 'Pre-built Templates ', 'shopbuilder' ); ?>
493 + <span id="modallabelPrefix"></span>
494 + </label>
495 + <div class="rtsb-tb-button-wrapper">
496 + <a class="btn" href="https://shopbuilderwp.com/themes/" target="_blank" style="opacity: 1; visibility: visible;">View Out Themes</a>
497 + </div>
405 498 </div>
499 + <div class="set-default-layout" data-has-pro="<?php echo esc_attr( rtsb()->has_pro() ); ?>" data-rest-url="<?php echo esc_url( rtsb()->BASE_API ); ?>" data-placeholder-image-src="<?php echo esc_url( $placeholderImageSrc ); ?>">
500 + <!-- Layout Will Add Via Ajax-->
501 + </div>
406 502 </div>
407 503 <?php } ?>
408 504 <input type="hidden" id="page_id" name="page_id" value="<?php echo esc_attr( $post_id ); ?>">
409 505 </div>
@@ -441,55 +537,20 @@
441 537 wp_send_json( $return );
442 538 wp_die();
443 539 }
444 540
445 - public function default_layout_template_html( $key, $is_checked, $builder, $value = [] ) {
446 - $layout_type = $key . ( $builder ? '_' . $builder : null );
447 - ?>
448 - <!-- Elementor -->
449 - <label class="layout-container type-<?php echo esc_attr( $key ); ?>"
450 - data-layout-type='<?php echo esc_attr( $layout_type ); ?>'>
451 - <input <?php echo esc_attr( $is_checked ); ?>
452 - class="rtsb-field" type="radio"
453 - value="<?php echo ! empty( $value['import_file'] ) ? esc_attr( $value['import_file'] ) : ''; ?>"
454 - name="import_default_layout"/>
455 -
456 - <span class="checkmark dashicons"></span>
457 - <div class="image-wrapper">
458 - <?php if ( ! empty( $value['image'] ) ) { ?>
459 - <img src="<?php echo esc_url( $value['image'] ); ?>" alt="">
460 - <?php } ?>
461 - </div>
462 - <?php if ( ! empty( $value['text_label'] ) ) { ?>
463 - <div class="image-label">
464 - <span class="label-text"><?php echo esc_html( $value['text_label'] ); ?></span>
465 - <?php if ( ! empty( $value['live_preview'] ) ) { ?>
466 - <a target="_blank" class="btn-live-preview" href="<?php echo esc_url( $value['live_preview'] ); ?>">
467 - <span class="dashicons dashicons-visibility"></span>
468 - <?php esc_html_e( 'Live Preview', 'shopbuilder' ); ?>
469 - </a>
470 - <?php } ?>
471 - </div>
472 - <?php } ?>
473 - </label>
474 - <?php
475 - }
476 -
477 541 /**
478 542 * Get Modal Card Markup.
479 543 *
480 - * @param $item
481 - * @param $checked
544 + * @param array $item Item.
482 545 *
483 546 * @return void
484 547 */
485 548 public function get_modal_card_html( $item ) {
486 -
487 549 ?>
488 550 <div class="layout-container rtsb-template-item type-<?php echo esc_attr( $item['template_type'] ); ?>"
489 551 data-layout-type='<?php echo esc_attr( $item['template_type'] ); ?>'>
490 552 <input class="rtsb-field" type="hidden" value="<?php echo esc_attr( $item['id'] ?? '' ); ?>" name="import_default_layout"/>
491 -
492 553 <div class="image-wrapper">
493 554 <?php if ( $item['image_url'] ) : ?>
494 555 <img src="<?php echo esc_url( $item['image_url'] ); ?>" alt="<?php echo esc_attr( $item['title'] ); ?>">
495 556 <?php endif; ?>
@@ -494,9 +555,10 @@
494 555 <img src="<?php echo esc_url( $item['image_url'] ); ?>" alt="<?php echo esc_attr( $item['title'] ); ?>">
495 556 <?php endif; ?>
496 557
497 558 <?php if ( 'default' != $item['template_type'] && ( ! rtsb()->has_pro() ) ) : ?>
498 - <div class="card-label">
559 + <div class="card-label lllllll">
560 + label
499 561 <span class="rtsb-btn-import <?php echo esc_attr( $item['status'] ?? 'free' ); ?>-btn">
500 562 <?php echo esc_html( $item['status'] ?? 'Free' ); ?>
501 563 </span>
502 564 </div>
@@ -514,9 +576,12 @@
514 576 <?php echo esc_html__( 'Preview', 'shopbuilder' ); ?>
515 577 </a>
516 578
517 579
518 - <?php if ( rtsb()->has_pro() || $item['status'] == 'free' ) : ?>
580 + <?php
581 + // phpcs:ignore WordPress.PHP.YodaConditions.NotYoda
582 + if ( rtsb()->has_pro() || $item['status'] == 'free' ) :
583 + ?>
519 584 <a class="rtsb-btn-import import-btn rtsb-import-layout">
520 585 <svg width="22" height="20" viewBox="0 0 22 20" fill="none" xmlns="http://www.w3.org/2000/svg">
521 586 <path d="M11 12.2295C10.9048 12.2296 10.8106 12.2113 10.7226 12.1757C10.6347 12.14 10.5547 12.0878 10.4874 12.0219C10.4201 11.956 10.3668 11.8778 10.3304 11.7917C10.294 11.7056 10.2753 11.6134 10.2754 11.5202L10.2754 0.912773C10.2754 0.72466 10.3517 0.544251 10.4876 0.411235C10.6235 0.278219 10.8078 0.203491 11 0.203491C11.1922 0.203491 11.3765 0.278219 11.5124 0.411235C11.6483 0.544251 11.7246 0.72466 11.7246 0.912773L11.7246 11.5202C11.7246 11.7083 11.6483 11.8887 11.5124 12.0218C11.3765 12.1548 11.1922 12.2295 11 12.2295Z"
522 587 fill="white"></path>
@@ -591,14 +656,17 @@
591 656 'content' => esc_html__( 'Empty string Not allowed...', 'shopbuilder' ),
592 657 ];
593 658 wp_send_json( $return );
594 659 }
660 + /** @noinspection SqlNoDataSourceInspection */
661 + /** @noinspection SqlResolve */
662 + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
595 663 $query = $wpdb->prepare(
596 - "SELECT ID, post_title
597 - FROM $wpdb->posts
598 - WHERE post_type = 'product'
599 - AND post_status = 'publish'
600 - AND post_title LIKE %s
664 + "SELECT ID, post_title
665 + FROM $wpdb->posts
666 + WHERE post_type = 'product'
667 + AND post_status = 'publish'
668 + AND post_title LIKE %s
601 669 LIMIT %d",
602 670 '%' . $search . '%',
603 671 10
604 672 );