Custom wp_query function - search post content - php

I have a php function that extends the default WP default search abilities (title & inside post content), it can now look in taxonomies / attributes too.
However, using the function results in the search query not looking inside post content, which is a feature I would like to retain. Would anyone be able to help tweak the below so the search still looks inside post content? Thank you
function and_extend_search( $search, &$wp_query ) {
global $wpdb;
if ( empty( $search ) ) {
return $search;
}
$terms = $wp_query->query_vars['s'];
$exploded = explode( ' ', $terms );
if ( $exploded === false || count( $exploded ) == 0 ) {
$exploded = array( 0 => $terms );
}
$search = '';
foreach ( $exploded as $tag ) {
$search .= " AND ( ($wpdb->posts.post_title LIKE '%$tag%') OR EXISTS ( SELECT * FROM $wpdb->term_relationships LEFT JOIN $wpdb->terms ON $wpdb->term_relationships.term_taxonomy_id = $wpdb->terms.term_id WHERE $wpdb->terms.name LIKE '%$tag%' AND $wpdb->term_relationships.object_id = $wpdb->posts.ID ) )";
}
return $search;
}

You have three errors here.
You put the parameter in your file as &$wp_query but you don't use this syntax in this case.
You clear out search $search = ''; before you try to concatenate it.
Your condition is AND instead of OR - Unless for some reason you're trying to limit it?
function and_extend_search( $search, $wp_query ) {
global $wpdb;
if ( empty( $search ) ) {
return $search;
}
$terms = $wp_query->query_vars['s'];
$exploded = explode( ' ', $terms );
if ( false === $exploded || 0 === count( $exploded ) ) {
$exploded = array( 0 => $terms );
}
foreach ( $exploded as $tag ) {
$search .= " OR ( ($wpdb->posts.post_title LIKE '%$tag%') OR EXISTS ( SELECT * FROM $wpdb->term_relationships LEFT JOIN $wpdb->terms ON $wpdb->term_relationships.term_taxonomy_id = $wpdb->terms.term_id WHERE $wpdb->terms.name LIKE '%$tag%' AND $wpdb->term_relationships.object_id = $wpdb->posts.ID ) )";
}
return $search;
}
add_filter( 'posts_search', 'and_extend_search', 500, 2 );

Related

add hook in product search query

I'm developing a plugin for my shopping site. The plugin works like this. Color variations of the same product are on different product pages. The products are connected together as shown in the photo below.
and on the product page as small photos, it is shown as color variants of the product.
It works flawlessly so far.
but I am using multi-vendor plugin on my website.
. I want it to search only the products belonging to the author, the user, that is the store, while selecting the product.
for this, is it possible to add a filter to the query made in the ajax request and rewrite the query?
add_filter('woocommerce_product_pre_search_products', 'woocommerce_product_pre_search_products', 10, 6);
function woocommerce_product_pre_search_products( $custom_query=false, $term, $type, $include_variations, $all_statuses, $limit) {
global $wpdb;
$post_types = $include_variations ? array( 'product', 'product_variation' ) : array( 'product' );
$join_query = '';
$type_where = '';
$status_where = '';
$limit_query = '';
// When searching variations we should include the parent's meta table for use in searches.
if ( $include_variations ) {
$join_query = " LEFT JOIN {$wpdb->wc_product_meta_lookup} parent_wc_product_meta_lookup
ON posts.post_type = 'product_variation' AND parent_wc_product_meta_lookup.product_id = posts.post_parent ";
}
/**
* Hook woocommerce_search_products_post_statuses.
*
* #since 3.7.0
* #param array $post_statuses List of post statuses.
*/
$post_statuses = apply_filters(
'woocommerce_search_products_post_statuses',
current_user_can( 'edit_private_products' ) ? array( 'private', 'publish' ) : array( 'publish' )
);
// See if search term contains OR keywords.
if ( stristr( $term, ' or ' ) ) {
$term_groups = preg_split( '/\s+or\s+/i', $term );
} else {
$term_groups = array( $term );
}
$search_where = '';
$search_queries = array();
foreach ( $term_groups as $term_group ) {
$search_terms = array( $term_group );
$term_group_query = '';
$searchand = '';
foreach ( $search_terms as $search_term ) {
$like = '%' . $wpdb->esc_like( $search_term ) . '%';
// Variations should also search the parent's meta table for fallback fields.
if ( $include_variations ) {
$variation_query = $wpdb->prepare( " OR ( wc_product_meta_lookup.sku = '' AND parent_wc_product_meta_lookup.sku LIKE %s ) ", $like );
} else {
$variation_query = '';
}
$term_group_query .= $wpdb->prepare( " {$searchand} ( ( posts.post_title LIKE %s) OR ( posts.post_excerpt LIKE %s) OR ( posts.post_content LIKE %s ) OR ( wc_product_meta_lookup.sku LIKE %s ) $variation_query)", $like, $like, $like, $like ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$searchand = ' AND ';
}
if ( $term_group_query ) {
$search_queries[] = $term_group_query;
}
}
if ( ! empty( $search_queries ) ) {
$search_where = ' AND (' . implode( ') OR (', $search_queries ) . ') ';
}
if ( ! empty( $include ) && is_array( $include ) ) {
$search_where .= ' AND posts.ID IN(' . implode( ',', array_map( 'absint', $include ) ) . ') ';
}
if ( ! empty( $exclude ) && is_array( $exclude ) ) {
$search_where .= ' AND posts.ID NOT IN(' . implode( ',', array_map( 'absint', $exclude ) ) . ') ';
}
$search_where .= ' AND posts.post_author='. get_current_user_id();
if ( 'virtual' === $type ) {
$type_where = ' AND ( wc_product_meta_lookup.virtual = 1 ) ';
} elseif ( 'downloadable' === $type ) {
$type_where = ' AND ( wc_product_meta_lookup.downloadable = 1 ) ';
}
if ( ! $all_statuses ) {
$status_where = " AND posts.post_status IN ('" . implode( "','", $post_statuses ) . "') ";
}
if ( $limit ) {
$limit_query = $wpdb->prepare( ' LIMIT %d ', $limit );
}
// phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
$search_results = $wpdb->get_results(
// phpcs:disable
"SELECT DISTINCT posts.ID as product_id, posts.post_parent as parent_id FROM {$wpdb->posts} posts
LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON posts.ID = wc_product_meta_lookup.product_id
$join_query
WHERE posts.post_type IN ('" . implode( "','", $post_types ) . "')
$search_where
$status_where
$type_where
ORDER BY posts.post_parent ASC, posts.post_title ASC
$limit_query
"
// phpcs:enable
);
$product_ids = wp_parse_id_list( array_merge( wp_list_pluck( $search_results, 'product_id' ), wp_list_pluck( $search_results, 'parent_id' ) ) );
if ( is_numeric( $term ) ) {
$post_id = absint( $term );
$post_type = get_post_type( $post_id );
if ( 'product_variation' === $post_type && $include_variations ) {
$product_ids[] = $post_id;
} elseif ( 'product' === $post_type ) {
$product_ids[] = $post_id;
}
$product_ids[] = wp_get_post_parent_id( $post_id );
}
return wp_parse_id_list( $product_ids );
}

In Woocommerce, how do I get price next to each variation?

I'm using the latest WC and I really want prices to show next to each variation, for a better overview.
I have trouble finding the proper code for my functions.php to display prices next to each variation. I saw several older posts and noone of them really worked.
I tried the following:
add_filter( 'woocommerce_variation_option_name', 'display_price_in_variation_option_name' );
function display_price_in_variation_option_name( $term ) {
global $wpdb, $product;
if ( empty( $term ) ) return $term;
if ( empty( $product->id ) ) return $term;
$result = $wpdb->get_col( "SELECT slug FROM {$wpdb->prefix}terms WHERE name = '$term'" );
$term_slug = ( !empty( $result ) ) ? $result[0] : $term;
$query = "SELECT postmeta.post_id AS product_id
FROM {$wpdb->prefix}postmeta AS postmeta
LEFT JOIN {$wpdb->prefix}posts AS products ON ( products.ID = postmeta.post_id )
WHERE postmeta.meta_key LIKE 'attribute_%'
AND postmeta.meta_value = '$term_slug'
AND products.post_parent = $product->id";
$variation_id = $wpdb->get_col( $query );
$parent = wp_get_post_parent_id( $variation_id[0] );
if ( $parent > 0 ) {
$_product = new WC_Product_Variation( $variation_id[0] );
return $term . ' (' . wp_kses( woocommerce_price( $_product->get_price() ), array() ) . ')';
}
return $term;
}
This one didn't work. I couldn't see any changes after implementing one way or the other. But its for older versions of WC, although Im beginning to believe that my theme is blocking it somehow. Im using Shopera.
Since there is no id argument woocommerce_variation_option_name, we could do this with script.
add_action( "wp_head", "function_to_woo_script" );
function function_to_woo_script () {
?>
<script>
$ = jQuery;
$(document).ready(function(){
var json_product = jQuery.parseJSON( $(".variations_form").attr("data-product_variations") );
var currency = "$";
for( i = 0; i < json_product.length; i++ ) {
var attr_name = $(".variations select").attr("data-attribute_name");
$(".variations select option[value='"+json_product[i].attributes[attr_name]+"']").html( json_product[i].attributes[attr_name] + " - " + currency + json_product[i].display_regular_price );
}
});
</script>
<?php
}
Result

Error in searching specific post_type form post_type column using WooCommerce product search

I am using this code to search products from a Wordpress/WooCommerce website.
My requirment is URL will be like "http://localhost/wp/?s=D34&post_type=product"
While s=D34 is search string.
When user will search for a string. Data will be searched from All default fields+ product's custom filed. The below code work fine with http://localhost/wp/?s=D34 but when &post_type=product is concatenated with url then it say
Code is given below
function cf_search_where( $where ) {
global $pagenow, $wpdb;
if ( is_search() ) {
$where = preg_replace("/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
"(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
$where .= " AND ($wpdb->posts.post_type = 'product') ";
}
return $where;
}
add_filter( 'posts_where', 'cf_search_where' );
This is to prevent distinct values
function cf_search_distinct( $where ) {
global $wpdb;
if ( is_search() ) {
return "DISTINCT"; //to prevent duplicates
}
return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );
So What modification is required?
URL http://localhost/wp/?orderby=price&post_type=product work fine
but what is wrong with http://localhost/wp/?s=D34&post_type=product
try this
function cf_search_where( $where ) {
global $pagenow, $wpdb;
// a little debugging will help you..
//print_r ($where);
//die();
if ( is_search() ) {
$where = preg_replace("/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
"(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
$where .= " AND ($wpdb->posts.post_type = 'product') ";
}
return $where;
}
add_filter( 'posts_where', 'cf_search_where' );
Based on your updated question.
if only you've used print_r ($where); to check what value does $where contains, you will see something like these...
with http://localhost/wp/?s=D34
AND (((wp1_posts.post_title LIKE '%D34%') OR (wp1_postmeta.meta_value LIKE '%D34%') OR (wp1_posts.post_content LIKE '%D34%')))
AND (wp1_posts.post_password = '')
AND wp1_posts.post_type IN ('post', 'page', 'attachment', 'product')
AND (wp1_posts.post_status = 'publish')
with http://localhost/wp/?s=D34&post_type=product
AND (((wp1_posts.post_title LIKE '%D34%') OR (wp1_postmeta.meta_value LIKE '%D34%') OR (wp1_posts.post_content LIKE '%D34%')))
AND (wp1_posts.post_password = '')
AND ( ( wp1_postmeta.meta_key = '_visibility' AND CAST(wp1_postmeta.meta_value AS CHAR) IN ('visible','search') ) )
AND wp1_posts.post_type = 'product'
AND (wp1_posts.post_status = 'publish')
take note of wp1_posts.post_type and get a hint.. be flexible on yourself and try to debug. above are results without the $where .= " AND ($wpdb->posts.post_type = 'product') "; though.

WordPress $wpdb->update set float to null?

Is there a way to set a column to NULL using $wpdb->update();?
When I attempt to, WordPress attempts to typecast that column to a float, which converts NULL to 0.
I've checked the core code and inside of $wpdb->update(), the $format parameter is only expecting %s, %f, and %d. I went so far as to set $wpdb->field_types['myCol'] to 'NULL', but both only serve to break $wpdb->update()'s query (interestingly enough, it shifts the values for each column over after the NULL).
There is a related question here, but that answer only deals with INSERT, not UPDATE.
From a data integrity standpoint, NULL is very important for this column, so I have to be able to set it as such when necessary.
As you yourself note, the $format parameter is only expecting %s, %f, and %d. The whole thing will get passed through prepare which also doesn't take a null format specifier because it basically accepts the same format specifiers that are accepted by (v)(s)printf but without the argument swapping. You can't pass NULL through update. You have the same choices as mentioned in the post suggested as a possible duplicate, and in essence it is.
Just don't use the update function. Write your own SQL and use it with $wpdb->query. If you are dealing with your own tables that should be fine.
Create your own database class that will do what you want. It is a little know fact that you can replace WordPress' $wpdb with a drop-in.
Here is a solution that modifies the wpdb from the latest version of wordpress, in order to allow inserting and updating null values into SQL tables using insert() and update():
/*
* Fix wpdb to allow inserting/updating of null values into tables
*/
class wpdbfixed extends wpdb
{
function insert($table, $data, $format = null) {
$type = 'INSERT';
if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
return false;
$this->insert_id = 0;
$formats = $format = (array) $format;
$fields = array_keys( $data );
$formatted_fields = array();
foreach ( $fields as $field ) {
if ( !empty( $format ) )
$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
elseif ( isset( $this->field_types[$field] ) )
$form = $this->field_types[$field];
else
$form = '%s';
//***edit begin here***
if ($data[$field]===null) {
unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted.
$formatted_fields[] = 'NULL';
} else {
$formatted_fields[] = $form; //Original line of code
}
//***edit ends here***
}
$sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
return $this->query( $this->prepare( $sql, $data ) );
}
function update($table, $data, $where, $format = null, $where_format = null)
{
if ( ! is_array( $data ) || ! is_array( $where ) )
return false;
$formats = $format = (array) $format;
$bits = $wheres = array();
foreach ( (array) array_keys( $data ) as $field ) {
if ( !empty( $format ) )
$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
//***edit begin here***
if ($data[$field]===null)
{
unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted.
$bits[] = "`$field` = NULL";
} else {
$bits[] = "`$field` = {$form}"; //Original line of code
}
//***edit ends here***
}
$where_formats = $where_format = (array) $where_format;
foreach ( (array) array_keys( $where ) as $field ) {
if ( !empty( $where_format ) )
$form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
elseif ( isset( $this->field_types[$field] ) )
$form = $this->field_types[$field];
else
$form = '%s';
$wheres[] = "`$field` = {$form}";
}
$sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
}
}
global $wpdb_allow_null;
$wpdb_allow_null = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
Insert this code into somewhere that always gets run, like your functions.php, and then use your new global $wpdb_allowed_null->insert() and ->update() as normal.
I preferred doing it this way vs. overriding the default $wpdb, in order to preserve the DB behavior that the rest of Wordpress and other plugins will expect.

Wordpress database insert() and update() - using NULL values

Wordpress ships with the wpdb class which handles CRUD operations. The two methods of this class that I'm interested in are the insert() (the C in CRUD) and update() (the U in CRUD).
A problem arises when I want to insert a NULL into a mysql database column - the wpdb class escapes PHP null variables to empty strings. How can I tell Wordpress to use an actual MySQL NULL instead of a MySQL string?
If you want it to compatible you would have to SHOW COLUMN and determine ahead if NULL is allowed. If it was allowed then if the value was empty($v) use val = NULL in the query.
$foo = null;
$metakey = "Harriet's Adages";
$metavalue = "WordPress' database interface is like Sunday Morning: Easy.";
if ($foo == null) {
$wpdb->query( $wpdb->prepare( "
INSERT INTO $wpdb->postmeta
( post_id, meta_key, meta_value, field_with_null )
VALUES ( %d, %s, %s, NULL )",
10, $metakey, $metavalue ) );
} else {
$wpdb->query( $wpdb->prepare( "
INSERT INTO $wpdb->postmeta
( post_id, meta_key, meta_value, field_with_null )
VALUES ( %d, %s, %s, %s)",
10, $metakey, $metavalue, $foo ) );
}
Here's a solution to your problem. In "wp-content" folder, create a file named "db.php" and put this code in it:
<?php
// setup a dummy wpdb to prevent the default one from being instanciated
$wpdb = new stdclass();
// include the base wpdb class to inherit from
//include ABSPATH . WPINC . "/wp-db.php";
class wpdbfixed extends wpdb
{
function insert($table, $data, $format = null) {
$formats = $format = (array) $format;
$fields = array_keys($data);
$formatted_fields = array();
$real_data = array();
foreach ( $fields as $field ) {
if ($data[$field]===null)
{
$formatted_fields[] = 'NULL';
continue;
}
if ( !empty($format) )
$form = ( $form = array_shift($formats) ) ? $form : $format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
$formatted_fields[] = "'".$form."'";
$real_data[] = $data[$field];
}
//$sql = "INSERT INTO <code>$table</code> (<code>" . implode( '</code>,<code>', $fields ) . "</code>) VALUES (" . implode( ",", $formatted_fields ) . ")";
$sql = "INSERT INTO $table (" . implode( ',', $fields ) . ") VALUES (" . implode( ",", $formatted_fields ) . ")";
return $this->query( $this->prepare( $sql, $real_data) );
}
function update($table, $data, $where, $format = null, $where_format = null)
{
if ( !is_array( $where ) )
return false;
$formats = $format = (array) $format;
$bits = $wheres = array();
$fields = (array) array_keys($data);
$real_data = array();
foreach ( $fields as $field ) {
if ($data[$field]===null)
{
$bits[] = "$field = NULL";
continue;
}
if ( !empty($format) )
$form = ( $form = array_shift($formats) ) ? $form : $format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
$bits[] = "$field = {$form}";
$real_data[] = $data[$field];
}
$where_formats = $where_format = (array) $where_format;
$fields = (array) array_keys($where);
foreach ( $fields as $field ) {
if ( !empty($where_format) )
$form = ( $form = array_shift($where_formats) ) ? $form : $where_format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
$wheres[] = "$field = {$form}";
}
$sql = "UPDATE $table SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
return $this->query( $this->prepare( $sql, array_merge($real_data, array_values($where))) );
}
}
$wpdb = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
?>
In this way you can use null values with wpdb!
I find this on Wordpress StackExchange forum and it works very well for me.
// Add a filter to replace the 'NULL' string with NULL
add_filter( 'query', 'wp_db_null_value' );
global $wpdb;
$wpdb->update(
'table',
array(
'status' => 'NULL',
),
array( 'id' => 1 )
);
// Remove the filter again:
remove_filter( 'query', 'wp_db_null_value' );
and the function wp_db_null_value is:
/**
* Replace the 'NULL' string with NULL
*
* #param string $query
* #return string $query
*/
function wp_db_null_value( $query )
{
return str_ireplace( "'NULL'", "NULL", $query );
}
Because in my case I cannot use $db->prepare() function...
wpdb insert() and update() works with NULL values, it was patched many years ago but never mentioned in the Codex.
In your case:
$wpdb->update(
'table',
array(
'status' => null,
),
array( 'id' => 1 ),
null,
'%d'
);
Ref: https://core.trac.wordpress.org/ticket/15158#no0
I tried to edit one of the other solutions listed here, because it resulted in the format array being misaligned with the data array, but failed.
Here is a solution that modifies the wpdb from the latest version of wordpress, in order to allow inserting and updating null values into SQL tables using insert() and update():
/*
* Fix wpdb to allow inserting/updating of null values into tables
*/
class wpdbfixed extends wpdb
{
function insert($table, $data, $format = null) {
$type = 'INSERT';
if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
return false;
$this->insert_id = 0;
$formats = $format = (array) $format;
$fields = array_keys( $data );
$formatted_fields = array();
foreach ( $fields as $field ) {
if ( !empty( $format ) )
$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
elseif ( isset( $this->field_types[$field] ) )
$form = $this->field_types[$field];
else
$form = '%s';
//***Steve Lee edit begin here***
if ($data[$field]===null) {
unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted.
$formatted_fields[] = 'NULL';
} else {
$formatted_fields[] = $form; //Original line of code
}
//***Steve Lee edit ends here***
}
$sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
return $this->query( $this->prepare( $sql, $data ) );
}
function update($table, $data, $where, $format = null, $where_format = null)
{
if ( ! is_array( $data ) || ! is_array( $where ) )
return false;
$formats = $format = (array) $format;
$bits = $wheres = array();
foreach ( (array) array_keys( $data ) as $field ) {
if ( !empty( $format ) )
$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
elseif ( isset($this->field_types[$field]) )
$form = $this->field_types[$field];
else
$form = '%s';
//***Steve Lee edit begin here***
if ($data[$field]===null)
{
unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted.
$bits[] = "`$field` = NULL";
} else {
$bits[] = "`$field` = {$form}"; //Original line of code
}
//***Steve Lee edit ends here***
}
$where_formats = $where_format = (array) $where_format;
foreach ( (array) array_keys( $where ) as $field ) {
if ( !empty( $where_format ) )
$form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
elseif ( isset( $this->field_types[$field] ) )
$form = $this->field_types[$field];
else
$form = '%s';
$wheres[] = "`$field` = {$form}";
}
$sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
}
}
global $wpdb_allow_null;
$wpdb_allow_null = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
Insert this code into somewhere that always gets run, like your functions.php, and then use your new global $wpdb_allowed_null->insert() and ->update() as normal.
I preferred this method vs. overriding the default $wpdb, in order to preserve the DB behavior that the rest of Wordpress and other plugins will expect.

Categories