msaari / relevanssi

Relevanssi, a WordPress plugin to improve the search
GNU General Public License v3.0
49 stars 21 forks source link

suppress php notice #18

Closed jnorell closed 4 years ago

jnorell commented 4 years ago

Some of the content being searched are multi-dimensional arrays (eg. a post created by SiteOrigins page builder) which triggers:

PHP Notice:  Array to string conversion in /path/to/wp-content/plugins/relevanssi/lib/excerpts-highlights.php on line 1106
jnorell commented 4 years ago

For that matter, maybe the array should be walked and content added from the various elements?

In my index settings I do have Custom fields set to visible, perhaps that is related if you try to reproduce it. But all the warnings do seem contain site origin page builder content in the $value.

msaari commented 4 years ago

Not going to merge this: the warning is an important thing to have, because it's telling you Relevanssi is getting data it can't handle. The correct solution is to change the data.

There's already a filter for that, too: you should use the relevanssi_custom_field_value filter hook to change the custom field content so that it's a preferably a string, with only the content you want to include in the index or in the excerpts (the same filter is applied to both indexing and excerpts).

jnorell commented 4 years ago

Makes sense, I'll track down docs for relevanssi_custom_field_value and do that.

Thanks

jnorell commented 4 years ago

If anyone else comes across this and needs some pointers, it appears that the issue happens when using site origin page builder the "old" way, before gutenberg - a site origin page layout block inside gutenberg doesn't seem to have the issue and is one workaround.

Alternately, when the issue does happen, it seems to frequently be in a field called 'panels_data', and the usable text fields within are all found under array keys of 'text', so you can walk the array pulling the 'text' fields to be searchable strings. I saw just a few other useful array keys (title, address and item_title), and came up with this:

/**
 * Relevanssi: handle custom field values for search
 */
add_filter( 'relevanssi_custom_field_value', function( $value, $field, $post_id ) {

        if ( is_array( $value ) ):
                $ret = [];

                array_walk_recursive( $value, function( $val, $key ) {
                        if ( in_array( $key, [ 'text', 'title', 'address', 'item_text' ] ) ):
                                $ret[] = $val;
                        endif;
                } );

                return $ret;
        endif;

        return $value;
}, 10, 3 );

Perhaps you'd even add this logic to the base version and make a relevanssi_custom_field_keys_to_index filter similar to relevanssi_custom_fields_to_index, to specify array keys to be indexed if the custom field is an array (and other keys ignored)?