There’s a lot going on in the code, so I rewrote your main function with some comments. Overview of notes:
$address_table
is superfluous, and also probably not what you wanted
You only use this variable once, so it’s safe to just in-line it in your query. Also, your use of $wpdb->prefix
expands $address_table
to the value “wp_wp_products
“, probably not what you want. I left it in the code with some notes, but you don’t need any of that in your final method, just use what’s in the $query
.
Early Return
Returning when your conditions fail, instead of doing logic when they pass (the is_search() && isset( $_GET['s'] )
block), makes your code more readable.
Escaping input
I know you were using $wpdb->prepare
eventually, but it doesn’t hurt to sanitize input as soon as you plan to use it. This way, if you pass $search
somewhere else later, it will hopefully be safer than it was when it came to your function. Also note the use of $wpdb->esc_like()
to prepare your search for use in a LIKE
clause.
function search_it() {
// Sanitize user input early, especially if assigning to a variable like later.
$search = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
// Early returns make your code more readable.
if ( ! is_search() || empty( $search ) ) {
return array();
}
global $wpdb;
/**
* Some things about `$address_table`:
* - You don't need double quotes if you're concatenating
* - You only use it in your query, see below where I incorporate it inline.
* - $wpdb->prefix is usually "wp_", so you're table comes out to "wp_wp_products" -
* I don't think that's what you want.
*/
$address_table = $wpdb->prefix . 'products';
// Double quote would look like this:
// $address_table = "{$wpdb->prefix}products";
// https://codex.wordpress.org/Class_Reference/wpdb/esc_like
$search = $wpdb->esc_like( $search );
$search = "%{$search}%";
// Why not prepare the whole query"?
// Also, you don't even need $address_table
$query = "SELECT * FROM {$wpdb->prefix}products WHERE SKU LIKE %s OR Details LIKE %s OR Page Like %s";
$query = $wpdb->prepare( $query, $search, $search, $search );
return $wpdb->get_results();
}
Please let me know if you have any questions.
Edit: I accidentally typed filter_validate
instead of filter_input
To address the second part of your code, it looks like the inner for
loop is using $start
and $end
, which aren’t defined. You also don’t need another loop since you’re already looping your results. Try this instead:
$cities = search_it();
if ( ! empty( $cities ) ) {
echo '<h1>Catalogue Search Results:</h1>';
echo "<table width="100%" align='center' border="3px solid grey">";
echo "<tr>";
echo "<th style="background: #B9C9FE;">Part Number</th>";
echo "<th style="background: #B9C9FE;">Description</th>";
echo "<th style="background: #B9C9FE;">Page</th>";
echo "</tr>";
echo "<tbody>";
foreach( $cities AS $city ) {
echo "<tr>";
echo "<td>{$city->SKU}</td>";
echo "<td>{$city->description}</td>";
echo "<td>{$city->Page}</td>";
echo "</tr>";
}
echo "</tbody>";
echo "</table>";
}