1

A website that was built a while ago by another developer that I am now maintaining has broken. I have been through the error logs and this is what I am seeing:

[04-Apr-2018 05:30:47 UTC] PHP Warning:  count(): Parameter must be an array or an object that implements Countable in /.../.../.../.../plugins/taxonomy-order/taxonomy-order.php on line 280

Now you might be thinking... why don't I just update the plugin. I wish, the plugin is no longer included on WordPress, the developer has removed his/her account and there is no support option. So I am now trying to fix this myself.

I have found the code that is causing the issue:

if( count( $taxonomies === 1 ) ) $taxonomy = array_shift( $taxonomies );

To try and give a bit more context here is the whole function:

public function terms_clauses( $clauses, $taxonomies, $args ) {
    global $wpdb;

    $taxonomies = (array) $taxonomies;

    if( count( $taxonomies === 1 ) ) $taxonomy = array_shift( $taxonomies );
    else return $clauses;

    if( !$this->has_taxonomy_support($taxonomy) ) return $clauses;

    // Fields
    if ( strpos( 'COUNT(*)', $clauses['fields'] ) === false ) $clauses['fields'] .= ', tm.meta_key, tm.meta_value ';

    // Join
    $clauses['join'] .= " LEFT JOIN {$wpdb->termmeta} AS tm ON (t.term_id = tm.term_id AND tm.meta_key = 'order') ";

    // Order
    if( isset( $args['menu_order'] ) && !$args['menu_order'] ) return $clauses; // menu_order is false when not added Order Clause

    // Default to ASC
    if( !isset( $args['menu_order'] ) || !in_array( strtoupper( $args['menu_order'] ), array( 'ASC', 'DESC' ) ) ) $args['menu_order'] = 'ASC';

    $order = "ORDER BY CAST(tm.meta_value AS SIGNED) " . $args['menu_order'];

    if ( $clauses['orderby'] ) {
        $clauses['orderby'] = str_replace('ORDER BY', $order . ',', $clauses['orderby'] );
    }else{
        $clauses['orderby'] = $order;
    }

    return $clauses;
}

And the usage:

add_filter( 'terms_clauses', array( $this, 'terms_clauses') , 10, 3 );

Unfortunately PHP is not a strong point of mine. I think I have figured out this is a bug due to new reules in PHP7 but I am not sure.

If anyone can help me resolve this issue I would be very greatful.

Cheers, Luke.

UPDATE

After @Norman's comments I have run his suggested code and this is the output I get:

Code:

if( count( $taxonomies ) == 1 ) {
    echo '<pre>';print_r($clauses);
    echo '</pre>';die('call');
}
else {
    return $clauses;
}

Result:

Array
(
    [fields] => t.*, tt.*
    [join] => INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id
    [where] => tt.taxonomy IN ('nav_menu') AND tt.count > 0
    [orderby] => ORDER BY t.name
    [order] => ASC
    [limits] => 
)
call

Issue is now fixed Thanks to the comment from Norman

lukehillonline
  • 2,430
  • 2
  • 32
  • 48
  • `if( count( $taxonomies === 1 ) )` shouldn't be like `if( count( $taxonomies ) == 1 )` also debug your code if it returns array when using `count()` functions – Noman Apr 04 '18 at 06:18
  • @Noman Not really sure how to debug it to be honest, I tried adding `'ini_set('display_errors', 'On');` but that didn't show any errors. – lukehillonline Apr 04 '18 at 06:36
  • `if( count( $taxonomies === 1 ) )` is this not setting `$taxonomies` to 1 as an int, while you are counting it? – Stender Apr 04 '18 at 06:38
  • 1
    change `if( count( $taxonomies === 1 ) )` to this `if( count( $taxonomies ) == 1 )` and then `echo '
    ';print_r($clauses);echo '
    ';die('call');` before `return $clauses;` to debug what is causing actually
    – Noman Apr 04 '18 at 06:40
  • if you run this `$taxonomies = '2hatever'; var_dump(count( $taxonomies === 1 ) );` it will return `1` - so you have to do, what @Noman tells you c",) – Stender Apr 04 '18 at 06:43
  • 1
    Regarding "Not really sure how to debug it to be honest" - If you don't wanna debug on the live site, but wanna check out small stuff like that, and don't exactly have a test environment for it, you can use online testers - like http://phptester.net/ – Stender Apr 04 '18 at 06:47
  • The `print_r` and `die('call')` is just for debugging - if the clauses looks fine, then change it accordingly. – Stender Apr 04 '18 at 06:59
  • @Noman Thanks, your code fixed the issue. If you post as an answer I will mark it for you. – lukehillonline Apr 04 '18 at 07:58
  • @lukehillonline added as answer, please review. – Noman Apr 04 '18 at 08:03

1 Answers1

1

you need to change the statement because when you get the count you need separately check for it returned data

It is not the PHP 7 issue it is the simple conditional statement error, you need to make sure when to use count, also you need to understand when to use == and === see difference here

if( count( $taxonomies === 1 ) )

to this if( count( $taxonomies ) == 1 )

and then echo '<pre>';print_r($clauses);echo '</pre>';die('call'); before return $clauses; to debug what is causing actually

Noman
  • 4,088
  • 1
  • 21
  • 36